Colaborare și concurență în Internet

Mihai Budiu -- mihaib+@cs.cmu.edu
http://www.cs.cmu.edu/~mihaib/

aprilie 2000

Subiect:
slăbiciuni exploatabile ale protocolului TCP
Cunoștințe necesare:
cunoștințe elementare despre rețele de calculatoare și TCP/IP
Cuvinte cheie:
fereastră, congestie, confirmare (acknowledgement)


Cuprins




Poate cel mai mare succes al ingineriei contemporane este Internetul. Acesta este cu siguranță cel mai mare sistem creat vreodată de umanitate, care leagă sute de milioane de utilizatori de pe toate continentele. Admirabilă este proiectarea sa, care a permis sistemului să crească și să funcționeze excelent la o scară nemaiîntîlnită.

Unele dintre calitățile sale derivă cu certitudine din faptul că a fost proiectat inițial ca o rețea militară, care este capabilă să supraviețuiască chiar unui atac nuclear, continuînd să funcționeze chiar în prezența distrugerii unei porțiuni substanțiale din infrastructură. Dar deși Internetul a fost proiectat pentru a rezista unor atacuri dinafara, nimeni nu a anticipat in design-ul original că multe probleme vor apărea dinauntru.

În acest articol voi prezenta trei astfel de slăbiciuni de concepție, care permit unor calculatoare lipsite de scrupule să interfere în mod dramatic cu comportarea rețelei. Vom vedea apoi și unele soluții propuse pentru a contra-ataca astfel de acțiuni.

Acest text este bazat pe un articol al lui Stephan Savage, un excelent cercetător în domeniul rețelelor de calculatoare, care în curînd își va obține doctoratul de la prestigioasa universitate Washington din Seattle.

Arhitectura Internetului

În PC Report au apărut o mulțime de articole despre arhitectura Internetului. Aceasta este conceptual simplă, dar destul de complicată pentru a umple o carte întreagă. De aceea, în această secțiune vom revizui doar unele dintre trăsăturile arhitecturale esențiale care ne vor permite să înțelegem de ce apar unele probleme.

Pietrele de temelie ale Internetului sunt două protocoale1 numite IP (Internet Protocol) și TCP (Transport Control Protocol). IP este un protocol foarte simplu, care rulează pe toate calculatoarele care compun Internetul; IP primește pachete de date de la un calculator cu rugămintea de a fi livrate la o anumită destinație, și încearcă să trimită pachetul acolo. Am vorbit despre IP cu mai multe ocazii (de pildă unul în PC Report din mai 1998, 'si unul in aprilie și mai 1999; puteți citi aceste articole din pagina mea de web).

În textul de față vom vorbi însă despre TCP. IP nu oferă nici un fel de garanții asupra datelor trimise; TCP se folosește de IP pentru a trimite date în mod ne-fiabil, dar repară lipsurile lui IP: TCP oferă o transmisiune complet fiabilă a tuturor datelor transmise de la un capăt la altul.

Protocolul TCP

De fapt protocolul TCP rezolvă nu mai puțin de trei probleme diferite simultan:

Conexiuni:
TCP construiește conexiuni virtuale între doi participanți la comunicație. Aceste conexiuni definesc durata comunicației: pachete trimise între aceleași două calculatoare în conexiuni diferite nu sunt confundate între ele. De asemenea, conexiunile rezervă resurse pe calculatoarele care participă la comunicație, pentru a face procesarea datelor eficientă (cam în același fel în care majoritatea limbajelor de programare oferă funcții speciale pentru a ``deschide'' fișiere și apoi pentru a accesa conținutul fișierelor). Managementul conexiunilor se face folosind niște mesaje speciale și un protocol simplu dar interesant numit ``strîngerea de mînă triplă'' (three-way handshake). În acest articol însă nu vom mai menționa stabilirea și desfacerea conexiunilor.

Fiabilitate:
TCP transformă comunicația ne-fiabilă oferită de IP într-o comunicație a unor fluxuri de date (streams) 100% fiabilă. Metoda folosită este absolut clasică: detecția pierderilor prin confirmări de la receptor (acknowledgements), și retransmiterea datelor pierdute pe parcurs. Vom vedea mai multe exemple despre folosirea (corectă și greșită) a aceste scheme.

Congestie:
în fine, TCP are o funcție foarte foarte importantă, anume controlul congestiei. Dacă sute de calculatoare încearcă să folosească un segment de rețea cu capacitate mică, TCP le permite să împartă în mod echitabil această resursă limitată.

În lipsa acestei funcțiuni a lui TCP, rețeaua ar intra rapid în ceea ce se numește colaps de congestie: calculatoarele ar trimite pachete mai repede decît rețeaua ar putea transporta, aceste pachete ar trebui să se piardă, ceea ce ar cauza re-transmiterea pachetelor pierdute, etc. Rezultatul ar fi întreruperea aproape completă a oricărei comunicații utile.

Specificația TCP

Protocoalele de funcționare a Internetului sunt publicate într-o formă extrem de bizară: sub forma unor documente numite ``Request For Comments'', sau RFC. Exista mai mult de 2000 de astfel de documente, dar nu toate sunt la fel de importante. Multe astfel de documente sunt de fapt vide (nu au fost niciodată publicate), unele sunt niște glume sau poezioare, iar unele sunt documente foarte serioase. Toate sunt disponibile în formă electronică într-o mulțime de locuri de pe Internet (normal, nu?).

Aceasta metodă de formalizare a arhitecturii stă într-un contrast dramatic față de metoda folosită de comitetele de standardizare internaționale, care publică documente extrem de groase, revizuite pentru multă vreme, si extrem de ``serioase''.

RFC-urile ilustrează evoluția extrem de rapidă și ``impulsivă'' (prin comparație) a Internetului; multe RFC-uri sunt revizuite în mod repetat.

Specificația TCP/IP se întinde pe mai multe RFC-uri. Definiția oficială a fost dată în 1981 în RFC 793. Corecții și lămuriri apar în RFC 1122. Din păcate alte detalii ale funcționării sale se întind efectiv pe zeci de RFC-uri.

Date și confirmări

TCP este un protocol simetric (full-duplex), în care ambele capete pot transmite date. E mai simplu însă să studiem problema ca și cum unul dintre participanți doar trimite date, iar celălalt doar le receptează.

Pentru a descrie comunicația vom folosi desene ca în figura 1.

Figura 1: O diagramă care indică schimbul de mesaje între emițător și receptor. Timpul este simbolizat de săgețile orizontale și curge spre dreapta. Săgețile oblice indică ``traiectoria'' pachetelor între emisie și recepție. Acest desen indică o conversație tipică, în care un pachet de date este trimis de emițător și o confirmare sosește apoi de la receptor. Vom prescurta pachetele de confirmare cu abrevierea standard, ACK (acknowledgement).
\begin{figure}\centerline{\epsfxsize=8cm\epsffile{comunicatii.eps}}\end{figure}

TCP funcționează cam ca scrisorile cu confirmare de primire de la poșta: poșta este un mecanism ne-fiabil de transmisiune, care pierde scrisori. De aceea trimițătorul poate să ceară în mod explicit ca cealaltă parte să confirme primirea plicului. Cînd poștașul livrează un plic, receptorul trebuie să semneze de primire. Apoi confirmarea de primire este trimisă înapoi tot prin poștă.

Pentru a obține fiabilitate, emițătorul așteaptă ce așteaptă, iar dacă nu primește nici o confirmare, mai trimite încă o dată scrisoarea. În clipa cînd a primit o confirmare, știe că scrisoarea a ajuns la celălalt capăt.

Observați că lipsa recepției unei confirmări poate indica două lucruri:

Ferestre glisante

Schema cu confirmare este foarte eficace pentru a combate pierderea de pachete, dar este ineficace dacă pachetele călătoresc mult timp pînă la destinație2. Pentru că pînă la întoarcerea primei confirmări emițățorul stă degeaba, o grămadă de resurse sunt irosite.

Din cauza asta, TCP încearcă sa trimită mai multe pachete la rînd, înainte de a primi confirmarea pentru fiecare din ele. Astfel, emițătorul menține o fereastră, care este lista pachetelor trimise dar încă ne-confirmate. De îndată ce primește confirmările, TCP avansează fereastra și trimite pachete noi.

Modul în care se încrucișează pachetele de date și confirmările este ilustrat de figura 4.

Figura 4: Pentru a nu irosi resursele rețelei, TCP de obicei trimite mai multe pachete înainte de a primi confirmarea primului. Această figură ilustrează o fereastră de emisie de dimensiune 3: TCP trimite trei pachete, și trimite apoi pachete noi doar dacă primește confirmări pentru cele trimise.
\begin{figure}\centerline{\epsfxsize=8cm\epsffile{fereastra.eps}}\end{figure}

Controlul congestiei

În fine, discutăm aici pe scurt despre modul în care TCP face față congestiei din rețea. Această secțiune este foarte importantă, pentru că toate cele trei atacuri pe care le discutăm în acest text manipulează slăbiciuni în specificarea și implementarea acestei scheme.

Asumpția de bază a lui TCP este că rețeaua de transmisiune este inerent fiabilă. TCP presupune că singura cauză de pierderi în rețea este congestia3.

Ce este congestia? Să ne imaginăm un ruter4 în rețea, care are trei interfețe de 1 megabit/secundă. Să ne imaginăm că pe două dintre interfețe se află niște trimițători care emit cu 800 kbps, iar pe a treia se află receptorul datelor. Ei bine, suma celor două fluxuri de 800 kbps depășește capacitatea legăturii spre receptor. Ca atare, pachetele care intră în ruter nu pot ieși toate în timp util. Ruterul va trebui să stocheze pachetele în exces în memoria internă. Dar dacă această situație durează destul de mult, ruterul trebuie să consume cîte 600 kbps de memorie pentru a stoca aceste pachete în exces. După 30 de secunde de trafic neîntrerupt, e nevoie de peste 2M de RAM. Atunci cînd memoria ruterului este complet utilizată, ruterul nu mai are nimic de făcut decît să renunțe la a mai trimite pachetele spre ieșire (pur și simplu sunt șterse din memorie). Aceasta este congestia, și rezultatul ei, pierderea de pachete.

Deci TCP își imaginează că atunci cînd un pachet nu este confirmat în timp util, s-a pierdut fie pachetul fie confirmarea, deci rețeaua este congestionată. Ca atare, trimițătorul imediat reduce rata de transmisiune, pentru a reduce numărul de pachete din rețea.

Dacă toți transmițătorii care detectează congestie reduc rata simultan, efectul este că ruterele din rețea primesc mai puține date la intrare, și au timp să golească pachetele stocate în memorie trimițindu-le la destinație. Pentru că marea majoritate a calculatoarelor din rețea folosesc protocolul TCP, acest comportament duce la dispariția congestiei.

Cum reduce emițătorul TCP rata de transmisiune? Într-un mod foarte simplu: reduce automat dimensiunea ferestrei, și mărește dimensiunea duratei de timeout. În felul acesta va face ca mai puține pachete să se afle simultan în rețea.

Colaborare și concurență în Internet

Am văzut pînă acum care sunt mecanismele prin care TCP își îndeplinește misiunile (unele dintre ele). Pentru a înțelege de ce aceste mecanisme nu sunt suficiente pentru orice scenariu, trebuie să aruncăm o privire asupra participanților la trafic din Internet și asupra intereselor lor contradictorii.

Spectrul participanților

Într-o excelentă expunere despre arhitectura Internetului, Stefan Savage a prezentat gradația din figura 5.

Figura 5: Intențiile participanților la comunicație în Internet variază între dorința de colaborare reciprocă pînă la intenții distructive. Proiectanții Internet-ului original au crezut că utilizatorii se vor plasa doar în regiunea ``cooperării''; situația de astăzi este însă net diferită.
\begin{figure}\centerline{\epsfxsize=12cm\epsffile{spectru.eps}}\end{figure}

Cooperare:
în continuare multe calculatoarelor din Internet cooperează pentru buna funcționare a rețelei. De exemplu, toate ruterele comunică între ele informații despre structura rețelei, ceea ce permite datelor să circule între oricare două puncte, chiar dacă ele aparțin unor domenii administrative distincte.

Indiferență:
probabil relația cea mai frecventă între două puncte terminale din Internet este cea de indiferență. De exemplu calculatorul de la www.agora.ro este indiferent la acțiunile mele, mai puțin dacă eu vreau sa obțin exact ceea ce el servește (pagini de web).

Între cooperare și indiferență este o distincție: de exemplu eu aș putea să doresc să măsor niște parametri ai rețelei între mine și calculatorul de la Agora, ca să știu de pildă unde se pierd pachete. Serverul de web www.agora.ro nu îmi va oferi însă nici un suport; nu are nici un avantaj din faptul că eu pot să măsor parametrii rețelei.

Concurență:
pe de altă parte între mine și oricare alt calculator care accesează același server de web este o relație de concurență: dacă serverul de web mi-ar consacra mie toate resursele, atunci aș primi un răspuns mult mai rapid și mai prompt. (Nu e vorba de concurență în sens economic, ci de competiție pentru resurse limitate ale rețelei.)

Dușmănie:
în fine, după cum stau mărturie capetele de afiș din lunile trecute, Internetul permite atacuri pe scară largă împotriva calculatoarelor conectate, de la intruziuni, furt de informație (care țin mai puțin de natura rețelei cît de implementarea sau administrarea defectuoasă a programelor), pînă la atacuri DOS (Denial of Service), care pot interzice accesul la anumite servicii (vedeți de pildă PC Report din martie 2000).

Competiție și fair-play

În acest articol ne vom focaliza doar asupra uneia dintre aceste relații competitive: relația de concurență. În orice context în care mai multe entități concurează asupra unui număr redus de resurse, vom avea de a face cu competiție. Pentru că în Internet avem de a face cu un număr uriaș de clienți potențiali, este virtual imposibil să avem resurse suficiente la dispoziție pentru a satisface pe deplin pe oricine. Așa că prezența competiției este absolut naturală. Atunci care e problema?

Problema este dacă nu cumva accesul la resurse nu este ``democratic''. În mod ideal fiecare client ar trebui să obțină la fel de multe resurse cît ceilalți clienți5.

Trebuie să fim deci pregătiți pentru competiție între feluriții participanți la trafic. Întrebarea este: asigură protocoalele din rețea o competiție ``onestă'' între participanți? Altfel spus, impun aceste protocoale un comportament echitabil? În mod normal ar trebui să fie imposibil să ``păcălim'' protocoalele în vreun fel. Un nod de comunicație în Internet nu are voie să aibă încredere în nimeni, nici măcar în cel cu care comunică în mod direct; de ce ar avea un site de web încredere în clienții care îi cer date? (Serviciul preponderent ca importanță -- în termeni de trafic sau importanță comercială -- în Internet este serviciul de web, așa că asupra lui ne vom concentra.)

Într-un articol scris de Ion Stoica în colaborare cu autorul celui de față, din PC Report din mai 1999, am arătat cum un transmițător care nu respectă semnalele de congestie (în acel caz un transmițător care folosea protocolul UDP, despre care nu am vorbit în acest text), poate căpăta avantaje în detrimentul tuturor celorlalți. Să zicem că un server refuză să asculte semnalele de congestie, și transmite tot timpul la maxim. Celelalte servere, cinstite, vor reduce traficul, și toată capacitatea rețelei va fi disponibilă pentru ticălos.

Atîta vreme cît traficul ``ticăloșilor'' nu cauzează congestie (adică capacitatea rețelei este suficientă pentru a transporta acest trafic), ticăloșii vor putea transmite la capacitate maximă, iar participanții onești nu vor transmite decît pe capacitatea rămasă. Dacă însă nu e sugicientă capacitate pentru cei incorecți, rețeaua ajunge imediat în colaps de congestie, și nimeni nu mai poate transmite nimic.

Și totuși rețeaua funcționează rezonabil. De ce oare? Ce împiedică comportamente anti-sociale pe scară largă?

Oportunitate și motiv

Aparent am putea fi tentați să spunem: deși protocoalele nu pot împiedica comportamente necinstite, totuși în practică nu le putem folosi în mod ilegal, din cauza separației între părți. Iată argumentul:

Pentru a putea comite o faptă anti-socială trebuie să avem două elemente deodată: motivul și ocazia. Să le analizăm pe fiecare în parte.

Motiv
Client
clienții sunt în directă competiție cu ceilalți clienți; un client are deci toate motivele să obțină cît mai mult trafic de la un server, în pofida celorlalți.
Server
putem spune același lucru despre servere: un server are toate intențiile să transmită cît mai multe date cît mai rapid, pentru a-și face proprii clienți cît mai satisfăcuți (în detrimentul clienților celorlalte servere de la concurență).
Oportunitate
Client
În traficul de web majoritatea datelor se merg de la server la client: clientul trimite o cerere de date, scurtă, iar serverul răspunde cu o cantitate mare de date. Clientul este un simplu ``receptor''. Aparent nu clientul nu poate face nimic pentru a căpăta mai multe date.
Server
Serverul are toate intențiile să trimită cît mai multe date posibil, în detrimentul celorlalte calculatoare care folosesc rețeaua: profitul pentru server este maxim cînd mai mulți clienți pot accesa informația. Aparent deci serverul poate ignora semnalele de reducere a congestiei din rețea, bazîndu-se pe faptul că celelalte servere vor micșora traficul, ceea ce îi va permite să transmită mai rapid.

În realitate lucrurile nu stau așa: studiile arată că în cazul serverelor mari de web ``gîtuitura'' în Internet este de fapt foarte aproape de server. Resursa critică deci nu e partea din rețea comună cu alte servere, ci chiar ``ieșirea'' serverului la Internet. Mărind congestia deci serverul își dă singur cu ciocanul peste degete.


Tabela 1: Oportunitate și motivație pentru a ``înșela'' ceilalți participanți la trafic. Căsuța marcată cu asterisk este de fapt incorect etichetată.
  Motiv Oportunitate
Client Da Nu$^*$
Server Da Nu


Trei atacuri asupra TCP

Iată deci că aparent cei care ar putea face rău (cei care trimit multe date, serverele) nu pot fi necinstiți, pentru că-și fac rău lor înșile, iar clienții nu pot face rău, pentru că ei nu transmit multe date, ci doar recepționează.

În realitate clienții au la dispoziție o unealtă foarte puternică cu care pot controla comportarea serverului, fără voia acestuia: confirmările.

Stefan Savage împreună cu colegii din grupul lui de cercetare au demonstrat acest lucru ``pe viu'': au luat un client linux și au făcut modificări minore în implementarea protocolului TCP (sub 100 de linii pentru toate atacurile prezentate la un loc). Apoi au demonstrat cum acest client, folosit pentru a extrage date de la mai multe site-uri de web foarte importante (deci care nu pot fi suspectate de colaborare), poate monopoliza rețeaua în detrimentul celorlalți clienți.

În cele ce urmează voi ilustra pe scurt trei modificări diferite și impactul fiecăreia dintre ele. Datele experimentale sunt din articolul citat.

Diviziunea confirmărilor

În TCP datele transmise formează un flux (stream). Fiecare pachet trimite o parte din date, și indică poziționarea lor în flux. De pildă, primul pachet ar putea trimite datele de la 0 la 1000, al doilea de la 1001 la 2000, etc. Confirmările pe de altă parte sunt cumulative: o confirmare care spune ``3001'' înseamnă: ``am primit toate datele între 0 și 3000; aștept date începînd de la 3001 în continuare''. În felul acesta, dacă o confirmare pentru un pachet se pierde (de exemplu cea pentru pachetul 1001-2000), confirmările ulterioare o pot subsuma, reducînd traficul necesar.

Primul atac e surprinzător de simplu: cînd receptorul primește un pachet, să zicem cu datele 0-1000, el va trimite în loc de o confirmare, trei: una pentru 333, una pentru 667, una pentru 1000. Atacul este ilustrat de figura 6.

Figura 6: Atacul prin diviziunea confirmărilor. Receptorul primește un singur pachet, dar confirmă mai multe bucățele.
\begin{figure}\centerline{\epsfxsize=8cm\epsffile{diviziune.eps}}\end{figure}

E clar că în felul acesta protocolul rămîne corect. Care e problema?

Problema este în modul în care emițătorul trebuie să reacționeze la astfel de mesaje: dacă citim în RFC 2581 vom vedea un paragraf care spune următoarele:

...cînd un pachet de confirmare este primit, trimițătorul mărește fereastra cu SMSS (Sender Maximum Segment Size)6.

Nu ne interesează prea tare cît e valoarea lui SMSS (această valoare este stabilită între cele două părți cînd se stabilește conexiunea); important e că, trimițînd mai multe confirmări, receptorul poate mări fereastra emițătorului aproape în mod arbitrar! Dacă alege să confirme fiecare octet, poate mări fereastra de mii de ori după un singur pachet primit! Figura 7 arată ce se întîmplă după aceea.

Figura 7: Rezultatul atacului prin diviziunea confirmării. Emițătorul crește fereastra cu o cantitate mare (SMSS) pentru fiecare confirmare primită, trimițînd o rafală de date imediat după primirea confirmărilor.
\begin{figure}\centerline{\epsfxsize=8cm\epsffile{diviziune-rezultat.eps}}\end{figure}

Asta înseamnă că emițătorul (serverul) va trimite apoi o rafală de pachete de date. Observați că pachetele sunt trimise unul după altul, înainte de a da o șansă rețelei să trimită semnale de congestie. În mod normal fereastra emițătorului crește treptat pînă atinge o valoare de echilibru, care nu produce congestie (această creștere se numește ``slow start''). Graficul din figura 8 arată că receptorul poate ``suge'' de la sursă documente uriașe aproape instantaneu.

Figura 8: Rata de transfer măsurată la client în Internet pentru două scheme: TCP normal și TCP modificat cu diviziunea confirmării. TCP-ul care trișează obține o rată de transfer uriașă, în detrimentul celorlalte calculatoare din rețea.
\begin{figure}\centerline{\epsfxsize=12cm\epsffile{diviziune-grafic.eps}}\end{figure}

Confirmări duplicate

A doua schemă este și mai simplă și se bazează pe aceeași slăbiciune din specificația TCP. În loc să trimită mai multe pachete de confirmare diferite, receptorul trimite în mod repetat un singur pachet de confirmare. Receptorul poate folosi chiar pachetul de confirmare pentru octetul 1 (ca și cum n-ar fi primit încă nimic).

Figurila 9 arată cum se comportă emițătorul. Performanța măsurată în Internet (și nu într-o rețea de laborator!) este aceeași ca pentru schema cu diviziune.

Această schemă este și mai perfidă decît cea precedentă; dacă pentru cea precedentă serverul ar putea să devină suspicios, pentru că sunt confirmate doar fragmente de pachet7. Din punct de vedere al serverului un scenariu în care vin mai multe confirmări identice este perfect plauzibil (protocolul IP nu promite că nu duplică pachete).

Figura 9: Rezultatul atacului prin duplicarea confirmărilor. Receptorul trimite mai multe confirmări identice; fiecare mărește mult fereastra emițătorului, care emite o apoi multe date.
\begin{figure}\centerline{\epsfxsize=8cm\epsffile{duplicate-rezultat.eps}}\end{figure}

Confirmări anticipate

În fine, ultimul atac este mai riscant, pentru că confirmă date care încă nu au fost primite. Ideea este că confirmările și datele se încrucișează pe parcurs, și serverul are impresia că datele au ajuns mult mai repede. Figura 10 arată cum funcționează acest atac.

Figura 10: Rezultatul atacului prin anticiparea confirmărilor. Receptorul trimite confirmări chiar pentru pachetele care nu au fost primite; aceste pachete rapid primite dau impresia că receptorul este foarte ``aproape'', și ca atare cauzează creșterea rapidă a ferestrei.
\begin{figure}\centerline{\epsfxsize=8cm\epsffile{anticipate-rezultat.eps}}\end{figure}

Desigur, în cazul unei pierderi reale de date, receptorul are probleme, pentru că emițătorul nu va re-trimite datele deja confirmate. Dar, așa cum arată cercetătorii de la U Washington, protocolul HTTP, prin care clientul comunică cu serverul de web8 permite clientului să re-ceară date de la server în mod selectiv. Deci pierderile la nivel TCP pot fi compensate de un client modificat prin nivele superioare de corecție a erorilor.

Performanțele schemei cu anticipare de confirmări sunt mai puțin spectaculoase, dar oricum, mult superioare celei a unui client normal (figura 11).

Figura 11: Performanță comparată măsurată în Internet a unui client normal și a unui client care folosește schema cu confirmări anticipate.
\begin{figure}\centerline{\epsfxsize=12cm\epsffile{anticipate-grafic.eps}}\end{figure}

Soluții

Partea cea mai neplăcută din toată povestea asta este că la ora actuală nu există nici un fel de soluții practice pentru a împiedica astfel de comportamente. Lucrările lui Savage și a echipei sale propun mai multe soluții, dar toate necesită schimbări în infrastructura Internetului, care schimbări sunt foarte greu de făcut și mai ales implementat pe scară largă.

Voi menționa doar pe scurt natura propusă a soluției; pentru detalii cei interesați pot vedea articolul original. Ideea ar fi ca emițătorul să poată ``verifica'' fiecare confirmare venită de la receptor, garantînd că acesta nu încalcă regulile. Pentru aceasta, emițătorul va pune în fiecare pachet un număr aleator diferit. Receptorul va trebui să includă în confirmare numărul cu pricina. Aceasta va preveni atacuri cu confirmări anticipate.

De asemenea, emițătorul va ține minte confirmările primite, și nu va crește fereastra pentru confirmări duplicate sau divizate.

Alte surse de informație

O listă a tuturor RFC-urilor cu opțiuni de căutare este prezentă la
http://www.cis.ohio-state.edu/hypertext/information/rfc.html.

RFC-ul de bază care descrie funcționarea TCP pentru prevenirea congestiei este RFC 2581 http://www.cis.ohio-state.edu/htbin/rfc/rfc2581.html.

Pagina de web a lui Stefan Savage este la http://www.cs.washington.edu/homes/savage.

Articolul lui Savage care a inspirat acest text este ``TCP Congestion Control with a Misbehaving Receiver'', Stefan Savage, Neal Cardwell, David Wetherall and Tom Anderson, ACM Computer Communications Review, pp. 71-78, v 29, no 5, October, 1999,
http://www.cs.washington.edu/homes/savage/papers/CCR99.ps.

Despre comportarea necinstită în Internet, efectele ei, și soluții, vedeți articolul ``Scalabilitatea în rețele de comunicații de date'', Ion Stoica și Mihai Budiu, din PC Report mai 1999, de asemenea la http://www.cs.cmu.edu/~mihaib/articles/csfq.ps.gz.

Pentru o descriere amplă și plăcută a funcționării Internetului vedeți de pildă cartea ``Internetworking with TCP/IP, volume I, Principles, Protocols and Architecture'', Douglas Comer, Prentice Hall 1995.

Un ghid interesant despre RFC-uri este la
http://www.netbook.cs.purdue.edu/othrpags/page24.htm. Acesta este de fapt o anexă a cărții mai sus-citate, care însă din păcate este ușor învechită (de exemplu RFC 2581 despre congestie nu este menționat de loc).



Note

... protocoale1
Un protocol este un set de reguli care descrie cum participanții la o discuție (calculatoarele) conversează între ei pentru a se înțelege.
... tie2
De fapt problema este indicată de mărimea care se numește capacitatea rețelei, care este produsul dintre lărgimea de bandă și durata propagării unui pachet; cu cît această valoare este mai mare, cu atît ineficiența unei scheme care așteaptă o confirmare înainte de a trimite un pachet este mai mare. Dar acest subiect depășește interesul acestui articol.
... congestia3
Acest lucru nu este adevărat în anumite tipuri de rețele, cum ar fi cele radio; de aceea TCP nu funcționează prea eficient cu aceste rețele.
... ruter4
Un ruter este un calculator intermediar în rețea, care servește drept una dintre legăturile dintre sursă și destinație.
... ti5
De fapt, mai cinstit ar fi ca fiecare să obțină după cum plătește, dar infrastructura Internetului contemporan nu permite o astfel de diferențiere; majoritatea cercetării din rețele de calculatoare se desfășoară în această direcție: cum putem oferi servicii cu calitate diferită pentru clienți diferiți (Quality of Service, QoS).
... Size)6
De fapt comportamentul protocolului este ușor diferit în timpul inițierii și după detectarea congestiei, dar calitativ rezultatul este același.
... pachet7
Rețeaua are dreptul să fragmenteze pachetele în bucăți, dar acest lucru se întîmplă foarte rar, pentru că adesea părțile ale o mărime de pachet suficient de mică pentru a nu fi nevoie să fie vreodată fragmentată, din motive de performanță.
... web8
HTTP folosește TCP pentru a transmite date, HTTP indică cum arată cererile și răspunsurile.