Vorgurakendused 2 prax 1 2014: erinevus redaktsioonide vahel

Allikas: Lambda
Mine navigeerimisribale Mine otsikasti
Resümee puudub
 
(ei näidata 2 kasutaja 16 vahepealset redaktsiooni)
2. rida: 2. rida:
<tr>
<tr>
<td>
<td>
 
[[Pilt:Robot300.jpg|Zombie robot attack]]
</td>
</td>
<td>
<td>
XXX
P2Net - P2P botnet
</td>
</td>
</tr>
</tr>
11. rida: 11. rida:
</table>
</table>


<b>TOORIK!!! TOORIK!!! OK variandiks muutub 6. septembriks! </b>
== <font color="red">NB! See on 2014 aasta praksi arhiiv, mitte hetkel kehtiv praks!</font> ==
 
<b>UUS: 16. oktoober tulge kohale, kui tahate katsetada oma P2Net implementatsiooni ühilduvust teistega. 23. oktoober selleks tõenäoliselt eriti aega pole, kuna kaitsmistel on prioriteet.</b>


Ülesandeks on ehitada P2P rakendus XXX programmide (käsurea kujul) käivitamiseks võõrastes masinates ja rehkendustulemuste kättesaamiseks, mis teeb laviinitaolise otsingu mööda XXX klient/servereid, isetehtud P2P mehhanismi abil.  
Ülesandeks on ehitada P2P rakendus P2Net programmide (käsurea kujul) käivitamiseks võõrastes masinates ja rehkendustulemuste kättesaamiseks, mis teeb laviinitaolise otsingu mööda P2Net klient/servereid, isetehtud P2P mehhanismi abil.  


Kasutajaliidese hea kvaliteet ei ole praksis oluline.
Kasutajaliidese hea kvaliteet ei ole praksis oluline.


Huvi korral võid vaadata ka veidi sarnaseid vanu ülesandeid [[Võrgurakendused 2013 prax 1 |2013 aasta arhiivis]] ning sealt edasi vanemaid.  
Huvi korral võid vaadata ka veidi sarnaseid vanu ülesandeid [[Vorgurakendused 2 prax 1 2013 |2013 aasta arhiivis]] ning sealt edasi vanemaid.  


   
   
== Üldkirjeldus ==
== Üldkirjeldus ==


XXX võimaldab:
P2Net võimaldab:


* kasutajal käivitada võõrastes masinatest käsurea.  
* kasutajal käivitada võõrastes masinatest käsurea.  
* saada tagasi käsurea rehkendatud tulemus(tekst/binary vms blob).
* saada tagasi käsurea rehkendatud tulemus(tekst/binary vms blob).
* idee on selle peale ehitada mingi rakendus, näit:
** mingite mahukate arvutuste jaotamine masinate vahel ([[#Näiterakendus]])
** web scrapingu (näit google otsingu) load balancing
** kaugadministreerimine
** ...
Rakenduse tegemine P2Net protokolli peale on ka praksi osa.


Võõraste masinate leidmiseks kasutab XXX järgmist viisi:
Võõraste masinate leidmiseks kasutab P2Net järgmist viisi:


* Saadab tema oma masinas oleva faili machines.txt masinatele failiotsingu päringu. machines.txt sees on masinate ip ja pordid json listina kujul  
* Saadab tema oma masinas oleva faili machines.txt masinatele käsu. machines.txt sees on masinate ip ja pordid json listina kujul  
<pre>
<pre>
[["11.22.33.44","2345"],...,["111.222.333.444","23456"]]
[["11.22.33.44","2345"],...,["111.222.333.444","23456"]]
</pre>
</pre>


* Samamoodi saadab käivitus-päringu XXX startlehel http://dijkstra.cs.ttu.ee/~tammet/XXX.txt olevatele masinatele (startlehel on plaintekstina eelmises punktis näidatud formaadis json-fail)
* Samamoodi saadab käivitus-päringu P2Net startlehel http://dijkstra.cs.ttu.ee/~priit/P2Net.txt olevatele masinatele (startlehel on plaintekstina eelmises punktis näidatud formaadis json-fail)
* Kui mingi masin saab minu päringu-käsurea kätte, siis ta paneb
* Kui mingi masin saab minu päringu-käsurea kätte, siis ta paneb selle kohapeal käsureal käima ja saadab tulemuse päringu algatanud masinasse.
selle  
leiab minu otsitud faili, siis ta saadab mulle teate, et mis IP ja pordiga masin ja mis täisnimega fail on.
* Iga võõras masin, mis algselt minu käest tulnud päringu saab, saadab ta omakorda kõigile talle teadaolevatele edasi, vähendades seejuures nn ttl (time to live) counti, et päringud lõpmatult rändama ei jääks.
* Iga võõras masin, mis algselt minu käest tulnud päringu saab, saadab ta omakorda kõigile talle teadaolevatele edasi, vähendades seejuures nn ttl (time to live) counti, et päringud lõpmatult rändama ei jääks.


Ehk, masinad saadavad minu antud päringut rekursiivselt ise edasi.
Ehk, masinad saadavad minu antud päringut rekursiivselt ise edasi.


Pane tähele, et sinu wazaa ei pea üldse salvestama võõraste wazaade ip-sid ja porte! Samas ei ole ka kuidagi keelatud (debugimiseks või niisama huvi pärast vms) salvestada teiste wazaade ip-sid, mida saab teada näiteks sulle tulnud päringutest, sulle vastajate ip-dest ja miks mitte ka portscannides :)
Pane tähele, et sinu P2Net ei pea üldse salvestama võõraste P2Net-ide ip-sid ja porte! Samas ei ole ka kuidagi keelatud (debugimiseks või niisama huvi pärast vms) salvestada teiste P2Net-ide ip-sid, mida saab teada näiteks sulle tulnud päringutest, sulle vastajate ip-dest ja miks mitte ka portscannides :)


== Miks just selline päringu edasisaatmisviis? ==
== Miks just selline päringu edasisaatmisviis? ==
48. rida: 55. rida:
Põhimõtteliselt saab päringut massidesse P2P meetoditega laiali saata kahel viisil:
Põhimõtteliselt saab päringut massidesse P2P meetoditega laiali saata kahel viisil:


* <b>Iteratiivne meetod</b> (antud praksis seda ei kasuta): algne masin küsib tuttavatelt neile tuttavate masinate faile, ja suurendab seeläbi endale teadaolevate masinate hulka. Igalt uuelt teadasaadud masinalt küsib ta jälle selle masina tuttavate faile jne. Teised masinad algset päringut ise kuhugi edasi ei saada. Meetodi pluss on see, et algne masin saab lihtsalt tagada, et päringut ei saadetaks kaks korda samale masinale. Meetodi miinus on see, et kõik masinad võrgus saadavad lõpuks terve neile tuttavate masinate faili algsele masinale: see tähendab väga suurt hulka väga suurte failide saatmisi, mis hakkavad jõhkralt ummistama võrku, ja algse masina väike kanal tõenäoliselt ummistub varsti. Saadud failide ühisosad on väga suured. Halvemal juhul saab algne masin N identset sõnumit, kus igaühes on N ip-d, kus N on kõigi masinate arv, kus jookseb wazaa.  
* <b>Iteratiivne meetod</b> (antud praksis seda ei kasuta): algne masin küsib tuttavatelt neile tuttavate masinate faile, ja suurendab seeläbi endale teadaolevate masinate hulka. Igalt uuelt teadasaadud masinalt küsib ta jälle selle masina tuttavate faile jne. Teised masinad algset päringut ise kuhugi edasi ei saada. Meetodi pluss on see, et algne masin saab lihtsalt tagada, et päringut ei saadetaks kaks korda samale masinale. Meetodi miinus on see, et kõik masinad võrgus saadavad lõpuks terve neile tuttavate masinate faili algsele masinale: see tähendab väga suurt hulka väga suurte failide saatmisi, mis hakkavad jõhkralt ummistama võrku, ja algse masina väike kanal tõenäoliselt ummistub varsti. Saadud failide ühisosad on väga suured. Halvemal juhul saab algne masin N identset sõnumit, kus igaühes on N ip-d, kus N on kõigi masinate arv, kus jookseb P2Net.  


* <b>Rekursiivne meetod</b> (antud praksis nõutud): algne masin saadab oma päringu tuttavatele masinatele, kes selle omakorda enda tuttavatele edasi saadavad jne. Igüks, kes leiab enda failide hulgast vajaliku faili, saadab info algsele masinale (vastasel korral ei saada ta algsele masinale midagi). Algne masin ei suurenda endale teadaolevate masinate hulka. Meetodi pluss on see, et algsele masinale saadetakse tagasi infot ainult siis, kui vajalik info leitakse (väga väike protsent masinaid) ja see info on lühike. Koormus võrgule langeb tugevasti ja algse masina kanal tõenäoliselt ei ummistu. Meetodi miinus on asjaolu, et üks ja sama masin võib saada algse päringu mitu korda eri suundadest, mis jällegi kasvatab võrgu koormust. Seda viimast probleemi saab  mitmel moel leevendada (kuigi mitte täielikult kaotada), eeskätt päringu ttl (time to live) parameetrit kasutades, päringu ahela masinate lisamises päringu parameetrite hulka jne.
* <b>Rekursiivne meetod</b> (antud praksis nõutud): algne masin saadab oma päringu tuttavatele masinatele, kes selle omakorda enda tuttavatele edasi saadavad jne. Igüks, kes leiab enda failide hulgast vajaliku faili, saadab info algsele masinale (vastasel korral ei saada ta algsele masinale midagi). Algne masin ei suurenda endale teadaolevate masinate hulka. Meetodi pluss on see, et algsele masinale saadetakse tagasi infot ainult siis, kui vajalik info leitakse (väga väike protsent masinaid) ja see info on lühike. Koormus võrgule langeb tugevasti ja algse masina kanal tõenäoliselt ei ummistu. Meetodi miinus on asjaolu, et üks ja sama masin võib saada algse päringu mitu korda eri suundadest, mis jällegi kasvatab võrgu koormust. Seda viimast probleemi saab  mitmel moel leevendada (kuigi mitte täielikult kaotada), eeskätt päringu ttl (time to live) parameetrit kasutades, päringu ahela masinate lisamises päringu parameetrite hulka jne.


Gnutella kasutab rekursiivset meetodit, nii ka meie wazaa. Lihtsakoeline rekursiivne meetod ummistab suure klientide arvu korral võrgu ja sele asemel kasutavad suured P2P süsteemid kas:
Gnutella kasutab rekursiivset meetodit, nii ka meie P2Net. Lihtsakoeline rekursiivne meetod ummistab suure klientide arvu korral võrgu ja sele asemel kasutavad suured P2P süsteemid kas:
* struktureeritud nn superpeeride süsteemi a la Kazaa ja esialgne Skype, kus rekursiivne päring toimub ainult superpeeride vahel, ja neid on vähe, või
* struktureeritud nn superpeeride süsteemi a la Kazaa ja esialgne Skype, kus rekursiivne päring toimub ainult superpeeride vahel, ja neid on vähe, või
* väga kavalat nn distributed hash tables (DHT) mehhanismi, a la freenet ja (osaliselt) bittorrent. DHT on üks mitmest bittorrenti poolt kasutatud meetodist, kuigi bittorrenti põhifookus on hoopis faili paralleelse allatõmbamise optimeerimisel mitme masina koostöös, mitte masinate/failide leidmisel. Või:
* väga kavalat nn distributed hash tables (DHT) mehhanismi, a la freenet ja (osaliselt) bittorrent. DHT on üks mitmest bittorrenti poolt kasutatud meetodist, kuigi bittorrenti põhifookus on hoopis faili paralleelse allatõmbamise optimeerimisel mitme masina koostöös, mitte masinate/failide leidmisel. Või:
61. rida: 68. rida:
Programmeerimiskeele ja muu tehnoloogia valik on vaba, kuid rakendus peab vastama neile tingimustele:
Programmeerimiskeele ja muu tehnoloogia valik on vaba, kuid rakendus peab vastama neile tingimustele:


* Kogu programm peab töötama kas AK klassi arvutis või sinu oma läptopis, mis AK klassis kaasas. Mingit kaugel asuvat serverit põhirakenduse jaoks kasutada ei tohi. Arusaadavalt võib aga panna wazaad lisaks käima ka suvalistesse välistesse masinatesse, et neilt faile küsida.
* Kogu programm peab töötama kas ITC-maja klassi arvutis või sinu oma läptopis, mis ITC maja klassis kaasas. Mingit kaugel asuvat serverit põhirakenduse jaoks kasutada ei tohi. Arusaadavalt võib aga panna P2Net lisaks käima ka suvalistesse välistesse masinatesse.
* Http protokolli jms realisatsioon peab olema teie oma programmi osa, mingit "suurt" http serverit a la apache kasutada ei või. Kõikvõimalike võrguteekide (versus eraldiseisvad veebiserverid) kasutamine on ok, mikroserverite koodi integreerimine oma programmi on ok.
* Http protokolli jms realisatsioon peab olema teie oma programmi osa, mingit "suurt" http serverit a la apache kasutada ei või. Kõikvõimalike võrguteekide (versus eraldiseisvad veebiserverid) kasutamine on ok, mikroserverite koodi integreerimine oma programmi on ok.


68. rida: 75. rida:
=== Otsipäringu saatmine ja edasisaatmine ===
=== Otsipäringu saatmine ja edasisaatmine ===


Konkreetselt masinalt 11.22.33.44 (kus wazaa jookseb pordis 2345) sobivate failide pärimine
Konkreetsele masinale 11.22.33.44 (kus P2Net jookseb pordis 2345) käsu saatmine


<pre>
<pre>
http://11.22.33.44:2345/searchfile?name=filename&sendip=55.66.77.88&sendport=6788&ttl=5&id=wqeqwe23&noask=11.22.33.44_111.222.333.444 ...
http://11.22.33.44:2345/run?prog=käsurida&sendip=55.66.77.88&sendport=6788&ttl=5&id=wqeqwe23&noask=11.22.33.44_111.222.333.444 ...
</pre>
</pre>


kus parameetritel on järgmine sisu:
kus parameetritel on järgmine sisu:


* name: otsitav string (peab olema failinimes)
* prog: käsk
* sendip: esialgse otsija ip
* sendip: esialgse saatja ip
* sendport: esialgse otsija port
* sendport: esialgse saatja port
* ttl: kui mitu otsingu-hopi veel teha (iga edasiküsimine vähendab ühe võrra)
* ttl: kui mitu otsingu-hopi veel teha (iga edasiküsimine vähendab ühe võrra)
* id: optsionaalne päringu identifikaator
* id: optsionaalne päringu identifikaator
* noask: optsionaalne list masinatest, kellelt pole mõtet küsida (eraldajaks alakriips)
* noask: optsionaalne list masinatest, kellele pole mõtet edastada (eraldajaks alakriips)  
   
Päringu identifikaator ei pea tingimata üle terve võrgu unikaalne olema - lihtsam on ja ajab asja ära, kui
on saatva masina piires unikaalne.
 
prog parameeter peab ilmselt olema urlencoded, näit. midagi taolist:
 
<pre>
...&prog=ipconfig%20/displaydns&... 
</pre>


Päringu vastuseks on õnnestunud päringu korral number 0,
GET-päringu vastuseks on õnnestunud päringu korral number 0,
ebaõnnestunud päringu korral muu (vea)number. Vastuse mõte on eeskätt debugimise lihtsustamine ja vastust peaks pärija üldiselt ignoreerima. Wazaa peaks töötama edukalt ka juhul, kui ta saatmise peale ühenduse lihtsalt kinni paneb ja vastust kuulama ei hakka.
ebaõnnestunud päringu korral muu (vea)number. Vastuse mõte on eeskätt debugimise lihtsustamine ja vastust peaks pärija üldiselt ignoreerima. P2Net peaks töötama edukalt ka juhul, kui ta saatmise peale ühenduse lihtsalt kinni paneb ja vastust kuulama ei hakka.


Wazaale tulnud päringu edasisaatmine käib täpselt sama protokolliga, kuid edasi saadetakse veidi muudetud päring:
P2Net-le tulnud päringu edasisaatmine käib täpselt sama protokolliga, kuid edasi saadetakse veidi muudetud päring:


* ttl vähendatakse ühe võrra
* ttl vähendatakse ühe võrra
95. rida: 111. rida:
Seda päringut saab ka brauserist katsetada, kuigi brauser ei saa vastuseks midagi huvitavat peale debugimis-vastuse 0 või mingi veakoodi.
Seda päringut saab ka brauserist katsetada, kuigi brauser ei saa vastuseks midagi huvitavat peale debugimis-vastuse 0 või mingi veakoodi.


=== Leitud failist teadaandmine algsele pärijale ===
Klientide filtreerimine (juhul kui soovitakse juhtida mingit alamhulka masinatest) toimub programmi
käsurea kaudu. See osa ei ole kohustuslik vaid tuleneb konkreetsest rakendusest; protokollis see funktsionaalsus ei sisaldu.


post call urlile
 
=== Tulemuse tagastamine algsele pärijale ===
 
Vastus oleks http post meetodiga käivitatud programmi kogu väljundi saatmine algsele küsijale muutmata kujul
koos lisainfoga


<pre>
<pre>
http://11.22.33.44:2345/foundfile
http://11.22.33.44:2345/result
</pre>
</pre>
kus IP ja port on algse pärija omad ning post päringu sisu (peale headeris olevat tühja rida) on
 
json formaadis list failide täisnimedega a la
POST-itatud data:
 
<pre>
<pre>
{ "id": "wqeqwe23",
   {"sendip": "55.66.77.88",  
  "files":
    "sendport": "6788",
   [
    "id": "asasasas",
    {"ip":"11.22.33.66", "port":"5678", "name":"minufail1.txt"},
     "encoding": "ascii" või "base64",  
     ...
    "content": "failisisustring"}
    {"ip":"11.22.33.68", "port":"5678", "name":"xxfail1yy.txt"}
  ]
}
</pre>
</pre>


id peaks vastama esialgse saatja antud id-le, juhul kui seda kasutatakse.   
* id: esialgse päringu id (kui oli algselt antud)
* content: käsureaprogrammi väljund (kui ei ole plaintext, peaks olema base64-encodetud)
* encoding: mis formaadis content on
* sendip: tulemuse saatnud masina ip
* sendport: tulemuse saatnud masina port


kus elementidel on järgmine sisu:
Programm võiks ka mitte crashida, kui id puudu on, kuna id on optional (aga praktiline ja mõtekas on lisada).
 
* id: esialgse päringu id (kui oli algselt antud)
* name: täispikk leitud faili nimi
* ip: masina ip, kus antud fail asub
* port: masina wazaa port, kus antud fail asub


Postituse saaja vastab eduka kättesaamise korral arvu 0,
Postituse saaja vastab eduka kättesaamise korral arvu 0,
arusaamatuste korral mõne muu (vea) numbri. Jällegi, vastuse mõte on eeskätt debugimise lihtsustamine ja vastust peaks pärija üldiselt ignoreerima. Wazaa peaks töötama edukalt ka juhul, kui ta saatmise peale ühenduse lihtsalt kinni paneb ja vastust kuulama ei hakka.
arusaamatuste korral mõne muu (vea) numbri. Jällegi, vastuse mõte on eeskätt debugimise lihtsustamine ja vastust peaks pärija üldiselt ignoreerima. P2Net peaks töötama edukalt ka juhul, kui ta saatmise peale ühenduse lihtsalt kinni paneb ja vastust kuulama ei hakka.
 
=== Leitud faili küsimine ===
 
Konkreetselt masinalt 11.22.33.44 (kus wazaa jookseb pordis 2345) konkreetse faili küsimine:
 
<pre>
http://11.22.33.44:2345/getfile?fullname=fullfilename
</pre>
 
Viimasele, getfile päringule vastatakse faili saatmisega üle http protokolli (st headeris on kindlasti ka content-length ja mime type): seda päringut peaks katseks saama edukalt ka brauserist teha ja brauser peaks faili alla laadima.


== Praksi kaks osa ==
== Praksi kaks osa ==
141. rida: 151. rida:


* Teha http protokolli järgida suutev esmane rakendus.
* Teha http protokolli järgida suutev esmane rakendus.
* Lisada sinna kogu vajalik funktsionaalsus.
* Lisada sinna kogu vajalik funktsionaalsus:
** P2Net protokolli implementatsioon
** P2Net peale ehitatud rakendus (nagu data korjamine, web query hajutamine, lihtsustatud remote admin, ...). Vt ka [[#Näiterakendus]].


Http protokolli järgimise võimet kontrollitakse praksi eduka läbimise tingimusena.
Http protokolli järgimise võimet kontrollitakse praksi eduka läbimise tingimusena.
147. rida: 159. rida:
== Soovitusi ja ideid ==
== Soovitusi ja ideid ==


Arendamiseks ja testimiseks pead saama jooksutada oma masinas mitut erinevat koopiat omaenda wazaast, igaüks oma pordil, igaühel oma konfifail tuttavate masinatega ja oma kataloog jagatavate failidega.
Arendamiseks ja testimiseks pead saama jooksutada oma masinas mitut erinevat koopiat omaenda P2Net-st, igaüks oma pordil, igaühel oma konfifail tuttavate masinatega.


Hea mõte on teha wazaa käsurealt käivitavaks nii, et ta võtab kohe käsurealt pordinumbri parameetriks ning loeb siis oma konfifaili ja jagatavaid faile vastavast pordinumbrist tuletatud failipathist.
Hea mõte on teha P2Net käsurealt käivitavaks nii, et ta võtab kohe käsurealt pordinumbri parameetriks ning loeb siis oma konfifaili vastavast pordinumbrist tuletatud failipathist.


Wazaa peab päris kindlasti sisaldama või kasutama http serverit,  
P2Net peab päris kindlasti sisaldama või kasutama http serverit,  
muidu ei ole temaga võimalik väljast ühendust võtta. NB! See ei tähenda mingit nö suurt veebiserverit a la apache, vaid pigem ise kirjutatud väikest minimaalset serverit, mis pealegi ei pea veebilehti serveerima ja cgi-sid käivitama, vaid ainult teatud käskudele/parameetritele reageerima.
muidu ei ole temaga võimalik väljast ühendust võtta. NB! See ei tähenda mingit nö suurt veebiserverit a la apache, vaid pigem ise kirjutatud väikest minimaalset serverit, mis pealegi ei pea veebilehti serveerima ja cgi-sid käivitama, vaid ainult teatud käskudele/parameetritele reageerima.


180. rida: 192. rida:
<!-- * [http://heather.cs.ucdavis.edu/~matloff/Python/PyNet.pdf Pythoni socketiprogrammeerimise õpetus] -->
<!-- * [http://heather.cs.ucdavis.edu/~matloff/Python/PyNet.pdf Pythoni socketiprogrammeerimise õpetus] -->


== Firewall ja NAT ==
=== Näiterakendus ===


Firewallist läbi murdmise ja kinniste portidega ühendamise probleemiga ei pea selles praksis tegelema. Samas tähendab see, et ei ole kuigi lihtne teise masinaga tegelikult ühendust saada (ühes masinas debugimise võimaldamine ongi seepärast kriitiline).
Sisend on list sõnadest (näiteks faili kujul, kus igal real üks unikaalne sõna). Tahaks teada saada, millised neist sõnadest on üksteisega sarnased. Väljund võiks olla mapping, kus on sõna ning siis sellega sarnaste sõnade list. Sellist asja võib vaja minna juhul, kui ma tahan mingit sisenddatat, näiteks veebist scrapetud andmeid, normaliseerida - oletame et ma otsin sõna "serials", siis võiks mind tegelikult ka huvitada kohad, kus esineb sõna "serial" (süntaktiline sarnasus) või kui ma otsin sõna "truck", siis mind võib huvitada ka "lorry" (semantiline sarnasus, mida on küll tegelikult suht keeruline tuvastada).


Kes wazaa käima saab, võib mõelda välja ja realiseerida probleemi lahendamiseks sobiva vaheserveri: selle eest saab ekstrapunkte.  
Kuidas sellist mappingut tekitada? Proovime kõiki sõnu üksteisega paarikaupa võrrelda. Näiteks oletame, et mul on sõnad: <code>["oma", "masinas", "mitut", "erinevat", "koopiat", "omaenda"]</code>. Hakkame võrdlema: <code>"oma"</code> ja <code>"masinas"</code> ei ole sarnased, <code>"oma"</code> ja <code>"mitut"</code> ei ole sarnased jne. kuni jõuame <code>"oma"</code> ja <code>"omaenda"</code> juurde, mis võiks olla sarnased (see sõltub täpselt sellest, kuidas sarnasus defineeritud on). Sellega on <code>"oma"</code> läbi vaadatud, järgmiseks võtame <code>"masinas"</code>. Sõnaga <code>"oma"</code> pole seda enam tarvis võrrelda, järelikult alustame paarist <code>"masinas"</code> ja <code>"mitut"</code> ja nõnda edasi kuni lõpuni. Väljund võiks olla näiteks mapping <code>{"oma" : ["omaenda"], "omaenda": ["oma"]}</code>.


Võrgust infot otsides leiad kahte liiki teemasid, meie jaoks oluline on siit listist teine:
Selleks tuleb vaadata ''(n(n-1))/2'' paari, ehk sellel ülesandel on polünomiaalne keerukus ''O(n^2)''. Mida see tähendab? Kui ma võtan näitena toodud kuuesõnalise listi asemel mingi realistlikuma listi, kus on 6000 sõna, siis aeg, mis selle läbi töötamisele kulub, ei kasva mitte 1000 korda vaid umbkaudu 1000000 korda. Ehk siis suht kerge on jõuda kohta, kus me enam ei viitsi tulemust ära oodata, kuna selle leidmine võtab tunde.
* Tunneldamise artiklid, loe näiteks [http://en.wikipedia.org/wiki/HTTP_tunnel http tunnel] artiklit wikipediast ja [http://sebsauvage.net/punching/ seda artiklit] firewallist läbipääsemisest.
* UDP/TCP hole punching ja NAT traversal: arusaadava sissejuhatusena loe [http://www.h-online.com/security/features/How-Skype-Co-get-round-firewalls-747197.html Skype jms süsteemide meetoditest], sellele [http://www.portugal-a-programar.org/forum/index.php?topic=7852.0 väike täiendus]. Vaata ka [http://en.wikipedia.org/wiki/Session_Traversal_Utilities_for_NAT wikipedia utiliitide artiklit ja viiteid].  Detailsemalt/lisaks [http://www.brynosaurus.com/pub/net/p2pnat/ siit] ja [http://nutss.gforge.cis.cornell.edu/pub/imc05-tcpnat/ siit] ja [http://www.jdrosen.net/midcom_turn.html siit] ja [http://www.ietf.org/rfc/rfc3489.txt siit], keerulise vahendi leiab [http://natblaster.sourceforge.net/ siit]


NB! Seda kõike ei ole väga lihtne teha ja sinu wazaa (ja ka selle inimese wazaa, kellega suhtled) peab ka oskama seda vaheserverit kasutada. Ära hakka seda ehitama, kui nö lihtne wazaa veel ei tööta!
Antud ülesanne kuulub [http://en.wikipedia.org/wiki/Embarrassingly_parallel triviaalselt paralleelsete] ülesannete hulka. Kui meil on 60 masinat käepärast, siis saab töö nii jagada, et iga masin teeb ~1/60 vajaminevatest võrdlustest ning see võiks tuua tööaja tundidest jälle minutite peale tagasi. Kuidas asja võiks P2Neti peal teha:


Ekstra-lisapunktide saamise variant: realiseeri ja pane kõigile kasutatavaks firewalliprobleemi lahendamiseks sobiv vaheserver. Kirjuta kasutamise juhend ja näited, mida teised saaks soovi korral oma wazaa jaoks tarvitada (st panna nad sinu vaheserverit kasutama, nii et seda saaks ka arvutiklassist kasutada). Esimesed kaks gruppi, kes sellega hakkama saavad, saavad lisaks pooled praksipunktid!
* '''Partitsioneerimine'''. Oletame, et me teame, kui palju meil masinaid täpselt P2Net-iga liitunud on. Kui neid masinaid on ''k'', siis iga masin võiks võtta ''1/k''-ndiku sõnadest ette ja võrrelda neid kõigi sõnadega. Näiteks kolme masina korral meie kuuesõnalisel näitel võiks üks masin võrrelda sõna <code>"oma"</code> ja <code>"masinas"</code> kõigi teiste vastu, teine teha seda sõnadega <code>"mitut"</code> ja <code>"erinevat"</code> jne. Natuke ressurssi läheb siin raisku selle peale, et ühte paari võrreldakse kaks korda: esimene masin teeb võrdluse <code>"oma"</code> ja <code>"mitut"</code>, teine teeb ka <code>"mitut"</code> ja <code>"oma"</code>. Selle vältimisega ei ole mõtet vaeva näha, see on pigem kasulik (sellest hiljem veel). Järgmiseks tekib küsimus, kuidas juhtida masinaid nii, et me ei peaks igaühele otse käsku andma. Seda võib lahendada nii: 1.) panen päringule kaasa parameetri ''k'' ja URL-i, kust sisendandmed saab alla tõmmata 2.) iga masin arvutab <code>h=hash(omaip,omaport) % k</code> ja saab numbri ''h'' mis on vahemikus 0 kuni ''k-1''. 3.) iga masin teeb sisendandmete listist täpselt iga ''k''-nda sõna, nihkega ''h'': kui mul ''h=0'' ja masinaid on kokku 7, siis ma võtan ette sõnad 1,8,15,... .


== toorik!!! ==
* '''Sarnasuse arvutamine'''. Seda võib teha igat moodi, alates [http://en.wikipedia.org/wiki/Levenshtein_distance triviaalsest] kuni [http://en.wikipedia.org/wiki/List_of_natural_language_processing_toolkits#Natural_language_processing_tools põhjalikuni]; vt ka http://wordnet.princeton.edu/.


<pre>
* <b>Tulemuste kokku korjamine</b>. Iga masin saadab oma osalise mappingu päringu algatajale. See paneb need kokku umbes nii: kui ühest masinast saadi <code>{"koer": ["koera"]}</code> ja teisest <code>{"koerad": ["koera"]}</code>, siis me saaks sellest kokku järeldada ka midagi sellist: <code>{"koera":["koer", "koerad"]}</code>. Mismoodi tulemusi täpselt kokku panna, sõltub natuke, kas teie arust on sarnasuse seos sümmeetriline ja/või transitiivne.


Tähelepanelikumal tudengil võib tekkida küsimus, mis siis saab kui hash collision tekib ning mõni tükk üleliia tehakse ning mõni mitte kordagi. Selle probleemi jätame koduülesandeks, vihjeks ainult, et 1.) P2P rakendustes ei ole niikuinii mõtet loota, et kõik masinad algusest lõpuni ilusti võrgus kättesaadavad on ja ei crashi töö jooksul 2.) partitsioneerimise meetod, mida kasutasime, tekitab teatud ülekattuvuse.


Juhul kui ka selle näiterakenduse uurimine mingeid ideid ei tekitanud, võib ka sellesama asja realiseerida. Tasub ainult tähele panna, et see on tõenäoliselt natuke töömahukam, kui mõni ise välja mõeldud rakendus.


--------
== Firewall ja NAT ==


Firewallist läbi murdmise ja kinniste portidega ühendamise probleemiga ei pea selles praksis tegelema. Samas tähendab see, et ei ole kuigi lihtne teise masinaga tegelikult ühendust saada (ühes masinas debugimise võimaldamine ongi seepärast kriitiline).


http://11.22.33.44:2345/searchfile?
Kes P2Net käima saab, võib mõelda välja ja realiseerida probleemi lahendamiseks sobiva vaheserveri: selle eest saab ekstrapunkte.  
 
name=filename&
prog=käsurida
prog=ipconfig /displaydns  (urlencoded!!) 
    %20
   
sendip=55.66.77.88&sendport=6788
&ttl=5&id=wqeqwe23&noask=11.22.33.44_111.222.333.444 ...
ipfilter=11.22.33.44-11.22.33.44_20.22.33.44-20.22.33.44&
-----


Võrgust infot otsides leiad kahte liiki teemasid, meie jaoks oluline on siit listist teine:
* Tunneldamise artiklid, loe näiteks [http://en.wikipedia.org/wiki/HTTP_tunnel http tunnel] artiklit wikipediast ja [http://sebsauvage.net/punching/ seda artiklit] firewallist läbipääsemisest.
* UDP/TCP hole punching ja NAT traversal: arusaadava sissejuhatusena loe [http://www.h-online.com/security/features/How-Skype-Co-get-round-firewalls-747197.html Skype jms süsteemide meetoditest], sellele [http://www.portugal-a-programar.org/forum/index.php?topic=7852.0 väike täiendus]. Vaata ka [http://en.wikipedia.org/wiki/Session_Traversal_Utilities_for_NAT wikipedia utiliitide artiklit ja viiteid].  Detailsemalt/lisaks [http://www.brynosaurus.com/pub/net/p2pnat/ siit] ja [http://nutss.gforge.cis.cornell.edu/pub/imc05-tcpnat/ siit] ja [http://www.jdrosen.net/midcom_turn.html siit] ja [http://www.ietf.org/rfc/rfc3489.txt siit], keerulise vahendi leiab [http://natblaster.sourceforge.net/ siit]


NB! Seda kõike ei ole väga lihtne teha ja sinu P2Net (ja ka selle inimese P2Net, kellega suhtled) peab ka oskama seda vaheserverit kasutada. Ära hakka seda ehitama, kui nö lihtne P2Net veel ei tööta!


Ekstra-lisapunktide saamise variant: realiseeri ja pane kõigile kasutatavaks firewalliprobleemi lahendamiseks sobiv vaheserver. Kirjuta kasutamise juhend ja näited, mida teised saaks soovi korral oma P2Net jaoks tarvitada (st panna nad sinu vaheserverit kasutama, nii et seda saaks ka arvutiklassist kasutada). Esimesed kaks gruppi, kes sellega hakkama saavad, saavad lisaks pooled praksipunktid!
 
kus parameetritel on järgmine sisu:
 
    name: otsitav string (peab olema failinimes)
    sendip: esialgse otsija ip
    sendport: esialgse otsija port
    ttl: kui mitu otsingu-hopi veel teha (iga edasiküsimine vähendab ühe võrra)
    id: optsionaalne päringu identifikaator
    noask: optsionaalne list masinatest, kellelt pole mõtet küsida (eraldajaks alakriips)  
   
   
 
---------------
 
  vastus oleks http post meetodiga faili saatmine algsele küsijale muutmata kujul
  koos lisainfoga
 
  {"sendip": "55.66.77.88",  
    "sendport": "6788",
    "id": "asasasas",
    "encoding": "ascii" või "hex",  
    "content": "failisisustring"}
   
   
  F3AA34
   
  base64
   
  utf-8 moodi????
 


</pre>


== Punktiarvestusest ==
== Punktiarvestusest ==


Kui kõik eelnimetatu töötab vastu mõne teise grupi wazaad ja  
Kui P2Net protokoll töötab vastu mõne teise grupi P2Net-i, sellele on realiseeritud mingi
koodi suudetakse seletada, saab täispunktid.
rakendus ja koodi suudetakse seletada, saab täispunktid.


Kui teiste wazaa-programmidega ei suuda suhelda, aga iseenda koopiatega siiski, siis päris täispunkte ei saa.
Kui teiste P2Net-programmidega ei suuda suhelda, aga iseenda koopiatega siiski, siis päris täispunkte ei saa.

Viimane redaktsioon: 1. september 2015, kell 11:52

Zombie robot attack

P2Net - P2P botnet

NB! See on 2014 aasta praksi arhiiv, mitte hetkel kehtiv praks!

UUS: 16. oktoober tulge kohale, kui tahate katsetada oma P2Net implementatsiooni ühilduvust teistega. 23. oktoober selleks tõenäoliselt eriti aega pole, kuna kaitsmistel on prioriteet.

Ülesandeks on ehitada P2P rakendus P2Net programmide (käsurea kujul) käivitamiseks võõrastes masinates ja rehkendustulemuste kättesaamiseks, mis teeb laviinitaolise otsingu mööda P2Net klient/servereid, isetehtud P2P mehhanismi abil.

Kasutajaliidese hea kvaliteet ei ole praksis oluline.

Huvi korral võid vaadata ka veidi sarnaseid vanu ülesandeid 2013 aasta arhiivis ning sealt edasi vanemaid.


Üldkirjeldus

P2Net võimaldab:

  • kasutajal käivitada võõrastes masinatest käsurea.
  • saada tagasi käsurea rehkendatud tulemus(tekst/binary vms blob).
  • idee on selle peale ehitada mingi rakendus, näit:
    • mingite mahukate arvutuste jaotamine masinate vahel (#Näiterakendus)
    • web scrapingu (näit google otsingu) load balancing
    • kaugadministreerimine
    • ...

Rakenduse tegemine P2Net protokolli peale on ka praksi osa.

Võõraste masinate leidmiseks kasutab P2Net järgmist viisi:

  • Saadab tema oma masinas oleva faili machines.txt masinatele käsu. machines.txt sees on masinate ip ja pordid json listina kujul
[["11.22.33.44","2345"],...,["111.222.333.444","23456"]]
  • Samamoodi saadab käivitus-päringu P2Net startlehel http://dijkstra.cs.ttu.ee/~priit/P2Net.txt olevatele masinatele (startlehel on plaintekstina eelmises punktis näidatud formaadis json-fail)
  • Kui mingi masin saab minu päringu-käsurea kätte, siis ta paneb selle kohapeal käsureal käima ja saadab tulemuse päringu algatanud masinasse.
  • Iga võõras masin, mis algselt minu käest tulnud päringu saab, saadab ta omakorda kõigile talle teadaolevatele edasi, vähendades seejuures nn ttl (time to live) counti, et päringud lõpmatult rändama ei jääks.

Ehk, masinad saadavad minu antud päringut rekursiivselt ise edasi.

Pane tähele, et sinu P2Net ei pea üldse salvestama võõraste P2Net-ide ip-sid ja porte! Samas ei ole ka kuidagi keelatud (debugimiseks või niisama huvi pärast vms) salvestada teiste P2Net-ide ip-sid, mida saab teada näiteks sulle tulnud päringutest, sulle vastajate ip-dest ja miks mitte ka portscannides :)

Miks just selline päringu edasisaatmisviis?

Põhimõtteliselt saab päringut massidesse P2P meetoditega laiali saata kahel viisil:

  • Iteratiivne meetod (antud praksis seda ei kasuta): algne masin küsib tuttavatelt neile tuttavate masinate faile, ja suurendab seeläbi endale teadaolevate masinate hulka. Igalt uuelt teadasaadud masinalt küsib ta jälle selle masina tuttavate faile jne. Teised masinad algset päringut ise kuhugi edasi ei saada. Meetodi pluss on see, et algne masin saab lihtsalt tagada, et päringut ei saadetaks kaks korda samale masinale. Meetodi miinus on see, et kõik masinad võrgus saadavad lõpuks terve neile tuttavate masinate faili algsele masinale: see tähendab väga suurt hulka väga suurte failide saatmisi, mis hakkavad jõhkralt ummistama võrku, ja algse masina väike kanal tõenäoliselt ummistub varsti. Saadud failide ühisosad on väga suured. Halvemal juhul saab algne masin N identset sõnumit, kus igaühes on N ip-d, kus N on kõigi masinate arv, kus jookseb P2Net.
  • Rekursiivne meetod (antud praksis nõutud): algne masin saadab oma päringu tuttavatele masinatele, kes selle omakorda enda tuttavatele edasi saadavad jne. Igüks, kes leiab enda failide hulgast vajaliku faili, saadab info algsele masinale (vastasel korral ei saada ta algsele masinale midagi). Algne masin ei suurenda endale teadaolevate masinate hulka. Meetodi pluss on see, et algsele masinale saadetakse tagasi infot ainult siis, kui vajalik info leitakse (väga väike protsent masinaid) ja see info on lühike. Koormus võrgule langeb tugevasti ja algse masina kanal tõenäoliselt ei ummistu. Meetodi miinus on asjaolu, et üks ja sama masin võib saada algse päringu mitu korda eri suundadest, mis jällegi kasvatab võrgu koormust. Seda viimast probleemi saab mitmel moel leevendada (kuigi mitte täielikult kaotada), eeskätt päringu ttl (time to live) parameetrit kasutades, päringu ahela masinate lisamises päringu parameetrite hulka jne.

Gnutella kasutab rekursiivset meetodit, nii ka meie P2Net. Lihtsakoeline rekursiivne meetod ummistab suure klientide arvu korral võrgu ja sele asemel kasutavad suured P2P süsteemid kas:

  • struktureeritud nn superpeeride süsteemi a la Kazaa ja esialgne Skype, kus rekursiivne päring toimub ainult superpeeride vahel, ja neid on vähe, või
  • väga kavalat nn distributed hash tables (DHT) mehhanismi, a la freenet ja (osaliselt) bittorrent. DHT on üks mitmest bittorrenti poolt kasutatud meetodist, kuigi bittorrenti põhifookus on hoopis faili paralleelse allatõmbamise optimeerimisel mitme masina koostöös, mitte masinate/failide leidmisel. Või:
  • kasutavad masinate leidmiseks eeskätt tsentraalseid servereid, a la esialgne Napster või kaasaegne Skype

Tehnilised nõuded

Programmeerimiskeele ja muu tehnoloogia valik on vaba, kuid rakendus peab vastama neile tingimustele:

  • Kogu programm peab töötama kas ITC-maja klassi arvutis või sinu oma läptopis, mis ITC maja klassis kaasas. Mingit kaugel asuvat serverit põhirakenduse jaoks kasutada ei tohi. Arusaadavalt võib aga panna P2Net lisaks käima ka suvalistesse välistesse masinatesse.
  • Http protokolli jms realisatsioon peab olema teie oma programmi osa, mingit "suurt" http serverit a la apache kasutada ei või. Kõikvõimalike võrguteekide (versus eraldiseisvad veebiserverid) kasutamine on ok, mikroserverite koodi integreerimine oma programmi on ok.

Protokoll

Otsipäringu saatmine ja edasisaatmine

Konkreetsele masinale 11.22.33.44 (kus P2Net jookseb pordis 2345) käsu saatmine

http://11.22.33.44:2345/run?prog=käsurida&sendip=55.66.77.88&sendport=6788&ttl=5&id=wqeqwe23&noask=11.22.33.44_111.222.333.444 ...

kus parameetritel on järgmine sisu:

  • prog: käsk
  • sendip: esialgse saatja ip
  • sendport: esialgse saatja port
  • ttl: kui mitu otsingu-hopi veel teha (iga edasiküsimine vähendab ühe võrra)
  • id: optsionaalne päringu identifikaator
  • noask: optsionaalne list masinatest, kellele pole mõtet edastada (eraldajaks alakriips)

Päringu identifikaator ei pea tingimata üle terve võrgu unikaalne olema - lihtsam on ja ajab asja ära, kui on saatva masina piires unikaalne.

prog parameeter peab ilmselt olema urlencoded, näit. midagi taolist:

...&prog=ipconfig%20/displaydns&...   

GET-päringu vastuseks on õnnestunud päringu korral number 0, ebaõnnestunud päringu korral muu (vea)number. Vastuse mõte on eeskätt debugimise lihtsustamine ja vastust peaks pärija üldiselt ignoreerima. P2Net peaks töötama edukalt ka juhul, kui ta saatmise peale ühenduse lihtsalt kinni paneb ja vastust kuulama ei hakka.

P2Net-le tulnud päringu edasisaatmine käib täpselt sama protokolliga, kuid edasi saadetakse veidi muudetud päring:

  • ttl vähendatakse ühe võrra
  • optionaalselt: lisatakse oma masina ip noask parameetrile otsa

Seejuures ei saadeta päringut edasi, kui sissetulnud ttl oli 1 võ i vähem (st ttl=0 päringuid enam kuhugi ei saadeta)

Seda päringut saab ka brauserist katsetada, kuigi brauser ei saa vastuseks midagi huvitavat peale debugimis-vastuse 0 või mingi veakoodi.

Klientide filtreerimine (juhul kui soovitakse juhtida mingit alamhulka masinatest) toimub programmi käsurea kaudu. See osa ei ole kohustuslik vaid tuleneb konkreetsest rakendusest; protokollis see funktsionaalsus ei sisaldu.


Tulemuse tagastamine algsele pärijale

Vastus oleks http post meetodiga käivitatud programmi kogu väljundi saatmine algsele küsijale muutmata kujul koos lisainfoga

http://11.22.33.44:2345/result

POST-itatud data:

  {"sendip": "55.66.77.88", 
    "sendport": "6788",
    "id": "asasasas",
    "encoding": "ascii" või "base64",	  
    "content": "failisisustring"}

id peaks vastama esialgse saatja antud id-le, juhul kui seda kasutatakse.

  • id: esialgse päringu id (kui oli algselt antud)
  • content: käsureaprogrammi väljund (kui ei ole plaintext, peaks olema base64-encodetud)
  • encoding: mis formaadis content on
  • sendip: tulemuse saatnud masina ip
  • sendport: tulemuse saatnud masina port

Programm võiks ka mitte crashida, kui id puudu on, kuna id on optional (aga praktiline ja mõtekas on lisada).

Postituse saaja vastab eduka kättesaamise korral arvu 0, arusaamatuste korral mõne muu (vea) numbri. Jällegi, vastuse mõte on eeskätt debugimise lihtsustamine ja vastust peaks pärija üldiselt ignoreerima. P2Net peaks töötama edukalt ka juhul, kui ta saatmise peale ühenduse lihtsalt kinni paneb ja vastust kuulama ei hakka.

Praksi kaks osa

Väga soovitav on teha praks kahes osas ja esitada kaks korda ülevaatamiseks:

  • Teha http protokolli järgida suutev esmane rakendus.
  • Lisada sinna kogu vajalik funktsionaalsus:
    • P2Net protokolli implementatsioon
    • P2Net peale ehitatud rakendus (nagu data korjamine, web query hajutamine, lihtsustatud remote admin, ...). Vt ka #Näiterakendus.

Http protokolli järgimise võimet kontrollitakse praksi eduka läbimise tingimusena.

Soovitusi ja ideid

Arendamiseks ja testimiseks pead saama jooksutada oma masinas mitut erinevat koopiat omaenda P2Net-st, igaüks oma pordil, igaühel oma konfifail tuttavate masinatega.

Hea mõte on teha P2Net käsurealt käivitavaks nii, et ta võtab kohe käsurealt pordinumbri parameetriks ning loeb siis oma konfifaili vastavast pordinumbrist tuletatud failipathist.

P2Net peab päris kindlasti sisaldama või kasutama http serverit, muidu ei ole temaga võimalik väljast ühendust võtta. NB! See ei tähenda mingit nö suurt veebiserverit a la apache, vaid pigem ise kirjutatud väikest minimaalset serverit, mis pealegi ei pea veebilehti serveerima ja cgi-sid käivitama, vaid ainult teatud käskudele/parameetritele reageerima.

Server tuleb realiseerida ise, kasutades võrgust leitavaid näiteid mikro-http-serveri jaoks (tüüpiliselt paar lehekülge koodi). Selliseid näitekoode võib täiesti otse kasutada.

C jaoks on sobiv mikroserver näiteks tiny, java jaoks on see server väga hea väike näide, aga selgitava tekstita, ning selgitavate tekstidega servereid leiad mh siit ja siit.Loe java socketitest põhjalikumalt siit. Pythoni serverinäite saad siit. Http kohta võib lugeda näiteks siit.

Kasutajaliides võib olla tehtud aknaga, aga see ei ole kohustuslik: võib teha ka puhtalt käsurea rakenduse.

Rakendus on mõistlik teha nii, et annad käivitamisel ette pordi, millel ta räägib, ning kui seda porti ei ole antud, siis kasutad vaikimisi porti 1215 (1214 on Kazaa port).

Häid selgeid näiteid ja õpetusi socketite ja serveri tegemise kohta leiad veel siit:

Näiterakendus

Sisend on list sõnadest (näiteks faili kujul, kus igal real üks unikaalne sõna). Tahaks teada saada, millised neist sõnadest on üksteisega sarnased. Väljund võiks olla mapping, kus on sõna ning siis sellega sarnaste sõnade list. Sellist asja võib vaja minna juhul, kui ma tahan mingit sisenddatat, näiteks veebist scrapetud andmeid, normaliseerida - oletame et ma otsin sõna "serials", siis võiks mind tegelikult ka huvitada kohad, kus esineb sõna "serial" (süntaktiline sarnasus) või kui ma otsin sõna "truck", siis mind võib huvitada ka "lorry" (semantiline sarnasus, mida on küll tegelikult suht keeruline tuvastada).

Kuidas sellist mappingut tekitada? Proovime kõiki sõnu üksteisega paarikaupa võrrelda. Näiteks oletame, et mul on sõnad: ["oma", "masinas", "mitut", "erinevat", "koopiat", "omaenda"]. Hakkame võrdlema: "oma" ja "masinas" ei ole sarnased, "oma" ja "mitut" ei ole sarnased jne. kuni jõuame "oma" ja "omaenda" juurde, mis võiks olla sarnased (see sõltub täpselt sellest, kuidas sarnasus defineeritud on). Sellega on "oma" läbi vaadatud, järgmiseks võtame "masinas". Sõnaga "oma" pole seda enam tarvis võrrelda, järelikult alustame paarist "masinas" ja "mitut" ja nõnda edasi kuni lõpuni. Väljund võiks olla näiteks mapping {"oma" : ["omaenda"], "omaenda": ["oma"]}.

Selleks tuleb vaadata (n(n-1))/2 paari, ehk sellel ülesandel on polünomiaalne keerukus O(n^2). Mida see tähendab? Kui ma võtan näitena toodud kuuesõnalise listi asemel mingi realistlikuma listi, kus on 6000 sõna, siis aeg, mis selle läbi töötamisele kulub, ei kasva mitte 1000 korda vaid umbkaudu 1000000 korda. Ehk siis suht kerge on jõuda kohta, kus me enam ei viitsi tulemust ära oodata, kuna selle leidmine võtab tunde.

Antud ülesanne kuulub triviaalselt paralleelsete ülesannete hulka. Kui meil on 60 masinat käepärast, siis saab töö nii jagada, et iga masin teeb ~1/60 vajaminevatest võrdlustest ning see võiks tuua tööaja tundidest jälle minutite peale tagasi. Kuidas asja võiks P2Neti peal teha:

  • Partitsioneerimine. Oletame, et me teame, kui palju meil masinaid täpselt P2Net-iga liitunud on. Kui neid masinaid on k, siis iga masin võiks võtta 1/k-ndiku sõnadest ette ja võrrelda neid kõigi sõnadega. Näiteks kolme masina korral meie kuuesõnalisel näitel võiks üks masin võrrelda sõna "oma" ja "masinas" kõigi teiste vastu, teine teha seda sõnadega "mitut" ja "erinevat" jne. Natuke ressurssi läheb siin raisku selle peale, et ühte paari võrreldakse kaks korda: esimene masin teeb võrdluse "oma" ja "mitut", teine teeb ka "mitut" ja "oma". Selle vältimisega ei ole mõtet vaeva näha, see on pigem kasulik (sellest hiljem veel). Järgmiseks tekib küsimus, kuidas juhtida masinaid nii, et me ei peaks igaühele otse käsku andma. Seda võib lahendada nii: 1.) panen päringule kaasa parameetri k ja URL-i, kust sisendandmed saab alla tõmmata 2.) iga masin arvutab h=hash(omaip,omaport) % k ja saab numbri h mis on vahemikus 0 kuni k-1. 3.) iga masin teeb sisendandmete listist täpselt iga k-nda sõna, nihkega h: kui mul h=0 ja masinaid on kokku 7, siis ma võtan ette sõnad 1,8,15,... .
  • Tulemuste kokku korjamine. Iga masin saadab oma osalise mappingu päringu algatajale. See paneb need kokku umbes nii: kui ühest masinast saadi {"koer": ["koera"]} ja teisest {"koerad": ["koera"]}, siis me saaks sellest kokku järeldada ka midagi sellist: {"koera":["koer", "koerad"]}. Mismoodi tulemusi täpselt kokku panna, sõltub natuke, kas teie arust on sarnasuse seos sümmeetriline ja/või transitiivne.

Tähelepanelikumal tudengil võib tekkida küsimus, mis siis saab kui hash collision tekib ning mõni tükk üleliia tehakse ning mõni mitte kordagi. Selle probleemi jätame koduülesandeks, vihjeks ainult, et 1.) P2P rakendustes ei ole niikuinii mõtet loota, et kõik masinad algusest lõpuni ilusti võrgus kättesaadavad on ja ei crashi töö jooksul 2.) partitsioneerimise meetod, mida kasutasime, tekitab teatud ülekattuvuse.

Juhul kui ka selle näiterakenduse uurimine mingeid ideid ei tekitanud, võib ka sellesama asja realiseerida. Tasub ainult tähele panna, et see on tõenäoliselt natuke töömahukam, kui mõni ise välja mõeldud rakendus.

Firewall ja NAT

Firewallist läbi murdmise ja kinniste portidega ühendamise probleemiga ei pea selles praksis tegelema. Samas tähendab see, et ei ole kuigi lihtne teise masinaga tegelikult ühendust saada (ühes masinas debugimise võimaldamine ongi seepärast kriitiline).

Kes P2Net käima saab, võib mõelda välja ja realiseerida probleemi lahendamiseks sobiva vaheserveri: selle eest saab ekstrapunkte.

Võrgust infot otsides leiad kahte liiki teemasid, meie jaoks oluline on siit listist teine:

NB! Seda kõike ei ole väga lihtne teha ja sinu P2Net (ja ka selle inimese P2Net, kellega suhtled) peab ka oskama seda vaheserverit kasutada. Ära hakka seda ehitama, kui nö lihtne P2Net veel ei tööta!

Ekstra-lisapunktide saamise variant: realiseeri ja pane kõigile kasutatavaks firewalliprobleemi lahendamiseks sobiv vaheserver. Kirjuta kasutamise juhend ja näited, mida teised saaks soovi korral oma P2Net jaoks tarvitada (st panna nad sinu vaheserverit kasutama, nii et seda saaks ka arvutiklassist kasutada). Esimesed kaks gruppi, kes sellega hakkama saavad, saavad lisaks pooled praksipunktid!


Punktiarvestusest

Kui P2Net protokoll töötab vastu mõne teise grupi P2Net-i, sellele on realiseeritud mingi rakendus ja koodi suudetakse seletada, saab täispunktid.

Kui teiste P2Net-programmidega ei suuda suhelda, aga iseenda koopiatega siiski, siis päris täispunkte ei saa.