Conan
Moderator
Inregistrat: acum 17 ani
Postari: 198
|
|
UDP
Caracteristici UDP UDP (User Datagram Protocol) este un protocol de nivel transport construit special pentru a oferi un serviciu de comunicare cât mai simplu peste IP. Specificatiile protocolului au fost publicate în 1980 în RFC-ul cu numarul 7681.
Câteva caracteristici ale UDP-ului sunt:
este un serviciu de tip datagrama: cererile de trimitere de date primite de la nivelul superior sunt tratate independent; comunicarea are loc fara stabilirea unei legaturi (conection-less): nu exista mecanisme de stabilire si terminare a unei conexiuni deoarece toate datele sunt trimise în cadrul unui singur pachet IP, care eventual va fi supus fragmentarii; nu se garanteaza ajungerea ala destinatie a datelor (best effort): ajungerea la destinatie nu este anuntata sursei; datele transportate sunt protejate de o suma de control (introdusa ca optionala initial ea este trecuta ca necesara(must) în RFC 1122 care stabileste modul de comportare al clientilor în Internet); overhead-ul introdus este minim: doar 8 octeti. Câteva utilizari tipice ale UDP-ului:
servicii de rezolvare a numelor (DNS): deoarece întrebarile si raspunsurile scurte pot fi mai eficient implementate peste UDP; fluxuri multimedia: deoarece mecanismele complicate de control al fluxului ale TCP-ului ar deprecia interactivitatea; server de fisiere (NFS): deoarece acest tip de aplicatii sunt în general rulate în retele locale cu performante ridicate care nu necesita mecanismele TCP; managementul retelei (SNMP); protocoale de rutare (RIP).
Caracteristici UDP UDP (User Datagram Protocol) este un protocol de nivel transport construit special pentru a oferi un serviciu de comunicare cât mai simplu peste IP. Specificatiile protocolului au fost publicate în 1980 în RFC-ul cu numarul 7681.
Câteva caracteristici ale UDP-ului sunt:
- este un serviciu de tip datagrama: cererile de trimitere de date primite de la nivelul superior sunt tratate independent; comunicarea are loc fara stabilirea unei legaturi (conection-less): nu exista mecanisme de stabilire si terminare a unei conexiuni deoarece toate datele sunt trimise în cadrul unui singur pachet IP, care eventual va fi supus fragmentarii; nu se garanteaza ajungerea ala destinatie a datelor (best effort): ajungerea la destinatie nu este anuntata sursei; - datele transportate sunt protejate de o suma de control (introdusa ca optionala initial ea este trecuta ca necesara(must) în RFC 1122 care stabileste modul de comportare al clientilor în Internet); overhead-ul introdus este minim: doar 8 octeti.
Câteva utilizari tipice ale UDP-ului:
- servicii de rezolvare a numelor (DNS): deoarece întrebarile si raspunsurile scurte pot fi mai eficient implementate peste UDP; fluxuri multimedia: deoarece mecanismele complicate de control al fluxului ale TCP-ului ar deprecia interactivitatea; - server de fisiere (NFS): deoarece acest tip de aplicatii sunt în general rulate în retele locale cu performante ridicate care nu necesita mecanismele TCP; managementul retelei (SNMP); - protocoale de rutare (RIP).
Formatul pachetelor UDP
Antetul cuprinde:
- port sursa - 16 biti; Împreuna cu adresa IP a sursei acest numar identifica în mod unic locul de unde a fost trimis datagrama UDP;
- port destinatie - 16 biti Împreuna cu adresa IP a destinatiei acest numar identifica în mod unic destinatia dorita pentru datagrama UDP;
- lungimea pachetului UDP - 16 biti Lungimea minima masoara datagrama UDP cu tot cu antent si prin urmare are o valoare minima de 8 octeti.
- suma de control - 16 biti; Suma de control acopera întreg pachetul UDP cât si un pseudo antet de 12 octeti format din:
- adresa IP a sursei - 32 biti;
adresa IP a destinatiei - 32 biti;
- 8 biti de zero pentru aliniere;
- numarul protocolului UDP (17) reprezentat pe 8 biti;
- lungimea pachetului UDP - 16 biti
Deoarece suma de control necesita în calculul ei un numar multiplu de 16 octeti, la sfârsitul datelor se adauga un numar potrivit de octeti de zero. Daca suma este 0 atunci ea va fi stocata ca 65535 (toti bitii pe 1). Un 0 în câmpul de sumei de control indica faptul ca suma de control nu a fost calculata.
Observatie: chiar daca un client are inhibat (în mod explicit) calcului sumei de control el este obligat sa verifice suma pachetelor care sosesc si au suma calculata.
Caracteristici TCP Deoarece protocolul IP este de tip datagrama utilizarea lui direct în aplicatii, care in general au nevoie de conexiuni sigure, este mult prea anevoioasa. Din aceste motive peste IP a fost construit un alt protocol, TCP (transimission control protocol), care corecteaza aceste probleme. Prima definire se gaseste în RFC-ul cu numarul 793 si dateaza din septembrie 1981. Din cauza deselor congestii aparute în 1986 algoritmul care sta la baza TCP-ului este reanalizat si în octombrie 1989 în RFC-ul cu numarul 1122 este publicata o noua specificare, mult mai eficienta si neambigua, a TCP-ului. Noi probleme legate de viteze mari sunt tratate în RFC-ul 1323 iar în 2018 TCP-ul este extins pentru a permite confirmarile selective (selective acknowledge). Seria de RFC-urie fundamentale este încheiata de aparitia în 1989 a RFC-ului cu numarul 2581. În el se specifica foarte strict comportamentul care este permis pentru o implementare de TCP.
Alaturi de protocolul UDP, TCP se situeaza pe nivelul transport în ierarhia de protocoale, deci între nivelul aplicatie si nivelul retea. Dar, cu toate ca se bazeaza pe acelasi protocol (IP) ca si UDP, TCP furnizeaza catre nivelul aplicatie cu totul alt tip de servicii, servicii orientate-conexiune, sigure, de tip flux de octeti.
Termenul de orientat-conexiune presupune ca, între cele doua aplicatii care comunica utilizând TCP, trebuie sa se stabileasca o conexiune TCP înainte ca transferul de date sa aiba loc. Aceasta conexiune nu este efectiv una fizica ci virtuala, asemanator cum se întâmpla în sistemul de telefonie clasica: cineva formeaza un numar si abia în momentul în care cealalta persoana raspunde se poate începe conversatia. Fiind o conexiune host-la-host, nu exista notiunile de broadcast sau multicast.
Transferul sigur de date este asigurat în urmatorul mod:
Datele sunt împartite în bucati a caror dimensiune optima e determinata de TCP, spre deosebire de UDP care trimite datagrame UDP corespunzatoare cu dimensiunea datelor primite de la nivelul aplicatie. Unitatea de date trimisa de TCP catre nivelul retea poarta numele de segment.
Când TCP trimite un segment porneste un timer si daca nu se primeste confirmarea segmentului respectiv într-un anumit timp, îl retransmite. În momentul în care se primeste un segment TCP trimite o confirmare (din motive de eficienta aceasta poate fi amânata un anumit interval de timp). În headerul TCP este mentinuta o suma de control pentru detectarea modificarilor în date. Daca se receptioneaza un segment corupt TCP îl ignora urmând sa fie retransmis datorita neprimirii confirmarii. Deoarece segmentele TCP sunt transmise mai departe încapsulate în datagrame IP iar acestea pot ajunge în orice ordine, segmentele TCP pot ajunge în alta ordine decât cea în care au fost trimise. De aceea, la destinatie TCP-ul trebuie sa se foloseasca de numere de secventa pentru a reordona eventual segmentele înainte de a le livra catre nivelul aplicatie. De asemenea, TCP trebuie sa asigure ignorarea duplicatelor. TCP asigura controlul fluxului în conditiile în care viteza de trimitere a datelor de la sursa poate fi mult prea mare decât capacitatea de prelucrare de la destinatie. Serviciul oferit de TCP este de tip flux de octeti deoarece ofera garantii ca fluxul de date trimis de sursa va fi livrat fara modificari la destinatie. Comparativ, UDP-ul produce pentru fiecare transfer cerut de nivelul aplicatie, un pachet IP (care ulterior poate fi supus fragmentarii) care, daca ajunge la destinatie corect va fi livrat direct nivelului aplicatie fara a garanta în vreun fel ordinea.
Formatul pachetelor TCP
Antetul unui segment TCP cuprinde:
port sursa - 16 biti pentru specificarea portului aplicatiei transmitatoare port destinatie - 16 biti pentru specificarea portului aplicatiei ce receptioneaza segmentul TCP Aceste doua porturi, împreuna cu adresele ale sursei si destinatiei continute în antet-ul IP identifica în mod unic conexiunea. Pentru o pereche formata dintr-o adresa IP si un port se foloseste adesea denumirea de socket (denumire introdusa în specificatiile initiale ale protocolului TCP, în RFC 793).
numar de secventa - 32 biti Pentru a asigura un serviciu de tip flux de octeti TCP numeroteaza fiecare octet de date utilizând un numar de secventa. Numarul de secventa din cadrul antetului TCP specifica destinatiei care este primul octet din fluxul trimis. La initierea unei conexiuni, se seteaza flag-ul SYN si se alege aleator un numar de secventa de început utilizând un generator de numere de secventa, ISN (Initial sequence number). Numarul de secventa al primului octet de date va fi numarul generat, ISN, plus 1, deoarece pachetul de initiere (cu SYN setat) consuma si el un numar de secventa. Se va vedea mai departe ca si flag-ul de terminare a conexiunii, FIN, consuma si el un numar de secventa.
confirmare - 32 biti Reprezinta numarul de secventa al octetului de date pe care transmitatorul confirmarii se asteapta sa-l primeasca. Astfel, daca s-a receptionat octetul cu numarul de secventa x (în numerotatia sursei) pachetul de confirmare va avea flag-ul ACK setat si va contine numarul de confirmare x + 1. Trimiterea unui ACK nu consuma un numar de secventa deoarece atât acest câmp cât si flag-ul ACK fac parte din antet, si, dupa stabilirea conexiunii ambele câmpuri devin active. Acest mecanism nu permite confirmari selective pentru ca numarul de secventa specifica pâna unde s-au receptionat date. De exemplu, daca la destinatie au ajuns octetii 1-1024 si urmatorul segment primit contine octetii 2049-3072 nu se poate trimite confirmare pentru cel de-al doilea segment, deci confirmarea va cuprinde numarul de secventa 1025.
lungimea antetului - 4 biti Specifica dimensiunea antetului ca numar de cuvinte de 32 de biti (4 octeti). Antetul poate avea între 20 si 60 de octeti, deci valoarea acestui câmp va fi între 5 (5 x 4 = 20 octeti) si 15 (15 x 4 = 60).
6 biti rezervati pentru utilizari viitoare 6 biti de control reprezentând urmatoarele flag-uri ce pot fi setate simultan:
URG - câmpul urgent pointer este valid ACK - câmpul de confirmare este valid PSH - destinatia trebuie sa trimita datele catre nivelul aplicatie cât mai devreme RST - se doreste resetarea conexiunii SYN - initierea conexiunii FIN - închiderea conexiunii dimensiunea ferestrei - 16 biti Reprezinta numarul de octeti (începând cu numarul de secventa continut în câmpul de confirmare) pe care destinatia e dispusa sa-l primeasca. Este limitat la 65535 octeti dar, cu toate ca pare o limita destul de mare, exista situatii când se doresc valori mult mai mari. În acest scop se folosesc niste optiuni speciale descrise ceva mai târziu, care permit scalarea ferestrei.
suma de control - 16 biti Aceasta suma de control acopera întregul segment TCP (atât datele cât si antetul TCP) si, spre deosebire de UDP, este obligatoriu sa fie completat de transmitator si verificat de receptor. Dar, ca si în cazul UDP-ului, la calculul sumei de control se ia in considerare si o zona speciala de 12 octeti ce cuprinde pentru re-verificare câmpuri din antetul IP (adresa IP a sursei si a destinatiei)[aici tre sa' vina o referire la poza cu pseudo-antetu]. Dupa adaugarea acestui pseudo-antet datele se împart în cuvinte de 16 biti în vederea calcularii sumei de control, adaugându-se eventual si un octet de aliniere.
urgent pointer - 16 biti Este utilizat pentru specificarea deplasamentului ultimului octet de date trimis în regim urgent. Astfel, ultimul octet din secventa urgenta se obtine adunând acest câmp la numarul de secventa. Ce înseamna acest mod urgent de transmitere: exista situatii în care aplicatiile vor sa trimita date `neordonate`. Sa presupunem ca aplicatia a trimis catre nivelul transport o cantitate mare de date dar la un moment dat observa ceva în neregula si doreste sa anuleze operatia. Daca trimite o comanda de anulare aceasta va fi adaugata la sfârsitul sirului de octeti deci nu se va putea împiedica ajungerea acestora la nivelul aplicatie de la receptor. Activând modul urgent datele urgente (comanda de anulare) vor fi plasate la începutul pachetului. Aplicatiile mai cunoscute care folosesc acest mod sunt Telnet, Rlogin si FTP.
optiuni - pâna la 40 de octeti (figura 7.3) Cele mai utilizate optiuni sunt:
Sfârsit de optiuni (end of option) - 1 octet Este utilizat pentru alinierea datelor continute în câmpul de optiuni. Nu poate fi utilizat decât o singura data, marcându-se astfel sfârsitul optiunilor si începerea datelor efective. Daca pentru alinierea la un cuvânt de 32 de biti e nevoie de mai mult de 1 byte se va utiliza optiunea no operation. Orice apare dupa aceasta optiune pâna la începutul cuvântului urmator de 32 de biti e ignorat.
no operation - 1 octet Utilizat pentru alinierea la cuvinte de 32 de biti.
Dimensiunea maxima a segmentului (Maximum Segment Size (MSS)) - 16 biti În ciuda denumirii defineste lungimea maxima a datelor, nu dimensiunea întregului segment. Poate lua valori între 0 si 65535, valoarea implicita fiind 536. Aceasta optiune e valabila doar în pachetele de initiere a conexiunii (cele cu flag-ul SYN setat), fiecare parte facând cunoscuta dimensiunea maxima a datelor dispusa sa le primeasca într-un pachet. În principiu cu cât aceasta valoarea e mai mare e mai bine, (deoarece se recupereaza din spatiul ocupat de antetele TCP si IP) pâna când apare fragmentarea. Valoarea maxima la care se poate seta este MTU (Maximum Transfer Unit) minus dimensiunea antetului IP si TCP (1460 octeti în cazul Ethernet).
Factor de scalare a ferestrei (Window scale factor) - 1 octet Pentru situatiile în care se doreste utilizarea unei ferestre mai mare de 65535 bytes se poate utiliza acest câmp pentru marirea dimensiunii ferestrei. Noua dimensiune va fi: . Chiar daca factorul de scalare poate fi maxim 255, în cazul TCP/IP el nu poate depasi valoarea 16, deoarece dimensiunea maxima a ferestrei nu poate fi mai mare decât valoarea celui mai mare numar de secventa.
Acest factor se poate seta doar la initierea conexiunii. În timpul transferului de date se poate modifica dimensiunea ferestrei dar factorul de scalare ramâne acelasi. Daca cel care a initiat conexiunea a trimis în segmentul de initiere si acest factor dar în pachetul cu ACK destinatarul nu si-a trimis si el factorul, atunci se la considera 0 în ambele directii. Invers, daca cel care solicita deschiderea conexiunii nu seteaza factorul, destinatia nu va putea seta factorul de scalare.
Timestamp - 10 octeti Utilizat pentru retinerea timpului în vederea calcularii RTT (Round Trip Time). Câmpul timestamp e completat de sursa în momentul trimiterii segmentului. La destinatie valoarea este retinuta si copiata în câmpul timestamp echo reply al pachetului cu confirmarea. RTT-ul este calculat de sursa facând diferenta dintre timpul curent si aceasta valoare.
Initierea si terminarea unei conexiuni TCP
Protocolul de initiere Modul de transmisie în cazul protocolului TCP este full-duplex, deci sunt transmise date simultan în ambele directii. Aceasta presupune ca cel care initiaza conexiunea trebuie sa primeasca aprobarea celuilalt capat înainte de începerea transferului de date: sursa îsi anunta intentia de a initia o conexiune, destinatia trimite un pachet cu confirmarea cererii si un pachet de initiere a conexiunii de la el la sursa iar apoi sursa confirma cererea primita de la destinatie. Pasii 2 si 3 pot fi realizati prin trimiterea unui singur pachet, de aceea protocolul de initiere este cunoscut sub numele de three-way handshake.
În cadrul protocolului de initiere exista 2 tipuri de cereri de initiere: cerere activa (active open), initiata de clientul ce doreste sa stabileasca conexiunea cu serverul si cerere pasiva (passive open), din partea serverului.
Cei 3 pasi sunt:
Clientul trimite un segment cu flag-ul SYN setat si care contine portul sursa, portul de la destinatie si numarul de secventa generat initial (ISN) de la care se vor numerota octetii de la client catre server. Optional se pot stabili parametrii conexiunii prin setarea lungimii maxime a segmentelor (MSS) dispus sa le primeasca de la server, factorului de scalare a ferestrei. Acest prim segment nu contine nici un parametru de confirmare si de asemenea nu are rost sa contine sa seteze dimensiunea ferestrei. Al doilea segment e trimis de server si are un rol dublu: confirma segmentul primit de la client prin setarea flag-ului ACK si completeaza numarul de secventa cu numarul de secventa primit plus 1 si, al doilea rol, initializeaza conexiunea de la el catre client prin setarea flag-ului SYN si generarea unui numar de secventa initial ce va fi folosit în numerotarea octetilor de la server spre client. Pe lânga aceasta trebuie sa contina dimensiunea ferestrei si optional, poate seta factorul de scalare si dimensiunea maxima a segmentului acceptat. Clientul trimite un segment cu confirmarea cererii din partea serverului (ACK setat + completeaza numarul confirmat cu numarul de secventa primit + 1). Ca si în cazul pasului 2, trebuie sa seteze dimensiunea ferestrei. Acest pachet poate contine date.
1 Deschiderea simultana
Se poate întâmpla ca uneori cele doua capete care vor sa comunice sa încerce sa stabileasca conexiunea simultan. În acest caz, dupa ce fiecare a trimis segmentul de initiere (initiere activa), ambele vor trimite un segment cu SYN + ACK si se va stabili o singura conexiune, nu doua.
Protocolul de terminare Oricare dintre cele doua parti poate solicita închiderea conexiunii, dar conexiunea fiind full-duplex, transferul de date în celalalt sens poate continua (aceasta situatie e denumita half-close). O închidere completa a unei conexiuni TCP presupune urmatorii pasi:
Clientul trimite un segment cu flag-ul FIN activat, solicitând închiderea conexiunii. Serverul trimite un segment ACK confirmând primirea cererea. Numarul de confirmare se completeaza normal, ca numarul de secventa primit + 1 Serverul continua sa trimita date catre client si când doreste sa închida si el conexiunea trimite un segment cu FIN activat. Clientul trimite un pachet ACK confirmând închiderea conexiunii. Cel care initiaza primul procedura de închidere (trimite primul FIN) realizeaza o închidere activa (active close) iar celalalt capat o închidere pasiva (passive close). În mod normal cel care realizeaza initierea activa va fi primul ce va trimite FIN, dar oricare dintre cei doi poate închide activ conexiunea.
Terminarea simultana În mod similar cu deschiderea simultana exista posibilitatea ca ambele capete ale conexiunii TCP sa initieze simultan procedura de închidere a conexiunii. În acest caz ambele parti vor trimite FIN si vor astepta primirea unui ACK. În continuare fiecare va primi cererea de terminare si va trimite ACK. Se observa ca numarul de segmente transferate pentru realizarea închiderii conexiunii (4 segmente) este acelasi ca la terminarea normala.
Resetarea conexiunii
Exista situatii în care TCP doreste resetarea conexiunii. De exemplu daca se solicita initierea unei conexiuni la un port inexistent. În acest caz cealalta parte va trimite un segment cu bitul RST setat pentru a anula solicitarea. O alta situatie este atunci când se constata ca celalalt capat al conexiunii nu raspunde un anumit timp (timeout).
Diagrama de stari
Toate evenimentele ce au loc în timpul stabilirii conexiunii, transferului si închiderii conexiunii pot fi rezumate printr-un automat finit cunoscut sub numele de diagrama de stari. Dupa cum chiar numele sugereaza este o masina cu un numar limitat de stari. O stare este pastrata pâna în momentul aparitiei unui eveniment, moment în care se poate trece în alta stare si/sau efectua o actiune. Tabela: Starile diagramei de stari TCP Stare Descriere
CLOSED Nu exista conexiune. LISTEN Serverul asteapta cereri de la clienti. SYN_SENT Cerere de initiere (activa) a conexiunii. Se asteapta confirmarea. SYN_RCVD S-a primit o cerere de initiere conexiune. ESTABLISHED S-a stabilit conexiunea. FIN_WAIT_1 Aplicatia a solicitat închiderea conexiunii. FIN_WAIT_2 Serverul a acceptat închiderea conexiunii. CLOSING Ambele parti solicita simultan închiderea conexiunii. TIME_WAIT Conexiune închisa dar se asteapta ca pachetele retransmise sa dispara. CLOSE_WAIT Serverul asteapta închiderea dinspre partea aplicatiei. LAST_ACK Serverul a închis conexiunea. Asteapta ultima confirmare.
Controlul fluxului Controlul fluxului-reprezinta totalitatea algoritmilor care permit atingerea unei viteze de transfer punct-la-punct cât mai mare pentru toate conexiunile existente. În principal acesti algoritmi stabilesc modul în care segmentele si confirmarile trebuie trimise si ce actiuni trebuie executate în situatiile în care raspunsurile asteptate de la celalalt capat întârzie sa vina Întârzierea confirmarilor O modalitate simpla de generare a confirmarilor este de a trimite câte una pentru fiecare segment primit. Aceasta politica prezinta avantajul de a face comunicatia self-clocking însa este ineficienta daca segmentele care nu contin decât confirmari sunt urmate la scurta distanta (câteva zeci de milisecunde) de segmente ce contin date efective. Pentru a evita aceasta situatie se procedeaza2 la întârzierea (200ms este o valoare uzuala; în RFC 1122 se specifica o valoare maxima de 500ms) a segmentelor care contin doar confirmari. Aceasta strategie face posibil ca un raspuns generat de primirea unor date sa plece sper celalalt capat în acelasi segment cu confirmarea.
Observatie: deoarece este dificil de mentinut timere pentru fiecare confirmare diferenta de 200ms este calculata de un timer global. Din acest motiv modul efectiv de comportare poate fi descris si în felul urmator: când un segment nu contine decât o confirmare el este pus într-o coada ce va fi inspectata de un proces care din 200 în 200 ms trimite tot ce s-a acumulat în coada.
Algoritmul Nagle Acest algoritm3 încearca sa îmbunatateasca performantele exploatând urmatoarea caracteristica foarte des întâlnita în dialogul dintre doua statii: daca se încearca trimiterea unor date de dimensiune mica însa exista înca date neconfirmate de partener atunci ele sunt buffer-ate si trimise într-un segment mai mare când soseste confirmarea asteptata. În acest fel se poate evita generarea datagramelor mici (tinygrame) în situatia unei legaturi lente. În cazul unei legaturi rapide confirmarile vor veni repede si întârzierea introdusa de algoritm va neglijabila.
Exista însa si cazuri în care acest algoritm duce la deprecierea performantelor: mesajele scurte generate de miscarile mouse-ului în cazul folosirii unui server X Window sau utilizarea tastelor care trimit mai mult de un caracter (secvente escape). Pentru a rezolva aceste inconveninte API-ul de utilizare a TCP-ului trebuie sa ofere o modalitate de a dezactiva acest algoritm (în sistemele bazate pe socketi exista în acest scop optiunea TCP_NODELAY).
Fereastra glisanta
Algoritmul implementat de TCP pentru a implementa transferul sigur de date este cunoscut în teorie sub numele de Go-Back-N. În acest algoritm se utilizeaza numere de secventa pentru a distinge pachetele între ele si o coada (dimensiunea maxima a cozii reprezinta fereastra) de pachetele a caror confirmare se asteapta. Pachetele se împart în 4 categorii:
- pachete trimis si pentru care s-a primit confirmare - pachete trimise si pentru care se asteapta înca confirmarea - pachete care nu au fost trimise înca dar care nu depasesc limitele ferestrei si deci pot fi trimise - pachete care înca nu au fost trimite si care nici nu vor putea fi trimise decât dupa ce au fost trimise toate pachetele din categoria 3 si s-au primit o parte din confirmarile la pachetele din categoria 2
Daca confirmarile pentru pachetele din categoria 2 întârzie prea mult (un mecanism de timer-e informeaza asupra acestui lucru) atunci ele vor fi retrimise. În versiunea initiala TCP-ul nu permitea decât confirmari pozitive ceea ce înseamna ca avansarea ferestrei se va împotmoli la segmentele neconfirmate. Cum se poate evita aceasta situatie vom discuta în detaliu în capitolele urmatoare. O solutie foarte radicala o constituie introducerea de confirmari selective (acest lucru este realizat de RFC 2018 din octombrie 1996). Aceasta modifica face ca TCP-ul actual sa fie un hibrid de Go-Back-N si Selective Repeat. Deoarece dimensiunea ferestrei este anuntata la fiecare segment un client lent poate ca pe masura ce trimite confirmarile sa informeze despre progresul înregistrat la livrarea datelor urmatorului nivel (aplicatie). Daca datele vin prea repede pentru viteza cu care clientul proceseaza datele fereastra fereastra se va dimiua si chiar închide (acest lucru se realizeaza anuntând o fereastra de dimensiune zero).
Slow start Un transfer de date TCP poate sa înceapa prin transmiterea de segmente pâna la umplerea întregii ferestre dupa care fie se primesc confirmari care vor permite unor noi pachete sa fie trimise, fie vor expira timer-ele de retransmisie si se va începe retrimiterea pachetelor de la începutul ferestrei. Din pacate un astfel de comportament poate duce la pomparea în retea a unui numar de pachete prea mare pentru capacitatea disponibila efectiv, înrautatind congestia. Pentru a evita acest lucru s-a propus urmatoarea solutie4: initial se trimite un segment; dupa primirea confirmarii lui se trimit doua segmente; dupa sosirea confirmarilor pentru ele se trimit patru segmente si asa mai departe. La un moment dat fie vor începe sa se piarda segmente (un indiciu ca s-a atins capacitatea maxima a canalului) fie se va umple fereastra pe care o anunta cel care primeste. Trebuie sa remarcam ca datorita cresterii exponentiale a numarului de segmente se va atinge destul de repede una din cele doua situatii.
Modalitatea efectiva de implementare a acestui algoritm are la baza utilizarea unei ferestre de congestie (congestion window; cwnd) care este initializata cu dimensiunea unui segment (cwnd se calculeaza în octeti) si la fiecare pas este dublata; fereastra efectiva din cadrul careia se pot trimite segmente este data de minimul dintre ultima fereastra comunicata de partener si cwnd.
RTO(Retransmission Timeout)
Deoarece TCP trebuie sa functioneze în conditii variate de latenta modul în care se face retransmiterea trebuie sa fie cât mai flexibil (si simplu în acelasi timp, pentru a introduce un overhead cât mai mic). Timpul cât se asteapta venirea unei confirmari (retransmission timeout RTO) este calculat prin cronometrarea timpului care îi ia unui segment trimis sa fie confirmat. Pentru o anumita conexiune se cronometreaza câte un singur segment la un moment dat iar pe baza RTT-ului masurat se actualizeaza valoare RTO-ului.
În RFC 793 formula de calcul a RTO-ului este urmatoarea:
R<-alfa*R+(1-alfa)*M
unde este un estimare pentru media RTT-urilor, este o estimare pentru abaterea RTT-urilor fata de medie (o aproximatie suficienta pentru abaterea patratica medie care însa este mult mai costisitor de calculat), este diferenta dintre RTT-ul masurat () si estimarea curenta (). Coeficientul cu care este actualizata estimarea curenta are valoarea de iar cel cu care este actualizat estimarea abaterii este . La stabilirea unei conexiuni valorile pentru si sunt alese astfel încât sa rezulte un RTT de secunde si un de 3 secunde (aceste recomandari sunt facute de RFC 1122). Daca pentru un anumit segment nu se primeste confirmarea în intervalul indicat de el va fi retrimis si noul este dublat. Valoarea maxima admisa pentru este de 240 secunde. Deoarece în cazul retrimiterilor nu se poate determina cu exactitate caruia din segmentele trimise apartine confirmarea actualizarea estimarilor este amânata pâna când se reuseste trimiterea corecta (s-a primit confirmare) fara retransmitere(``din prima'') a unui segment. Acest artificiu (deloc neimportant) care permite evitarea actualizarea eronata a estimarilor este cunoscut sub numele de algoritmul lui Karn si a fost propus în 1987 de P. Karn si C. Partridge.
Evitarea congestiei Daca cei doi parteneri care comunica prelucreaza datele suficient de repede si vor sa transfere un volum mare de date atunci limitarea de care se vor lovi este cea data de viteza retelei. Din cauza modului ``best-effort'' pe care IP-ul îl ofera când canalul de comunicatie este saturat o parte din segmentele TCP se vor pierde. În mod poate paradoxal atât transmitatorului cât si receptorul se pot afla în pozitia de a fi primii în detectarea pierderii unui segment. Unul din indiciile de la transmitator care semnaleaza pierderea unui segment este (în mod evident) aparitia unui timeout a timer-ului de retransmisie. La nivelul receptorului un indiciu al posibilei pierderi a unui segment este primirea unor segmente out-of-order. Deoarece TCP-ul în varianta initiala nu permite decât confirmari pozitive singurul lucru pe care receptorul îl poate face este ca la fiecare segment out-of-order primit sa trimita o confirmare indicând prin aceasta ca la el continua sa vina segmente însa cel indicat de numarul de secventa de confirmare lipseste. Primirea acestor confirmari multiple este al doilea mod în care transmitatorul poate afla de aparitia congestiei.
Algoritmul ce trebuie aplicat în momentul în care se detecteaza aparitia congestiei este cunoscut sub numele de ``evitarea congestiei (congestion avoidence)''. Principiul care sta la baza lui este ca la aparitia congestiei fie sa se treaca la o incrementare liniara a dimensiunii ferestrei, daca congestia a fost detectata ca urmare a primirii unor confirmari identice repetate, fie sa se reia slow start-ul în cazul în care congestia s-a detectat prin expirarea unui timer de timeout. Implementarea acestui algoritm se bazeaza pe utilizarea unui nou contor (sstresh) care sa indice dimensiunea ferestrei de la care se trece de la incrementarea exponentiala la cea liniara. Algoritmul efectiv este urmatorul:
la stabilirea unei noi conexiuni se pleaca cu sstresh initializat la valoare de 64K si cwnd la dimensiunea unui segment trimiterea de segmente se face fara a depasi minimul dintre fereastra publicata de partener (pentru a nu depasi capacitatea de procesesare a partenerului) si cwnd-ul curent (pentru a nu depasi limita impusa de capacitatea retelei)
la aparitia congestiei sstresh este setat la jumatatea valorii ferestrei curente (minimul dintre fereastra anuntata de partener si cwnd însa cel putin dimensiunea corespunzatoare pentru doua segmente); daca congestia a fost detectata prin expirarea unui timer de timeout atunci cwnd este initializat cu dimensiunea unui segment la primirea unei confirmari incrementarea se face în doua moduri, în functie de relatie în care se afla cwnd si sstresh:
daca cwnd e mai mic sau egal cu sstresh se face incrementarea exponentiala caracteristica slow start-ului (care de fapt nu e deloc slow în cazul de fata) daca cwnd e mai mare ca sstresh atunci se face o incrementare cu dimensiunea unui segment.
Fast Retransmission, Fast Recovery Dupa cum am vazut un receptor care primeste segmente out-of-order va trimite transmitatorului confirmari duplicate. Algoritmul denumit ``fast retransmission'' recomanda urmatoarele doua comportamenet:
un receptor care detecteaza segmente out-of order trebuie sa nu întârzie trimiterea de confirmari (dupa cum am vazut în general confimarile sunt întârziate micsora numarul de pachete fara date care sunt transferate) un transmitator care care primeste mai mult de trei confirmari duplicate trebuie sa retrimita segmentul indicat ca fiind neprimit de confirmarile în cauza fara a astepta expirarea timer-ul de timeout
Algoritmul de ``fast recovery'' încearca sa optimizeze si mai mult comportamentul transmitatorului care detecteaza un numar de trei sau mai multe confimari duplicate. Mai exact el recomanda trecerea la actualizarea liniara a ferestrei (congestion avoidance). Acest tip de comportament se poate justifica prin urmatorul rationament: deoarece înca mai sunt transferate date între cei doi parteneri (si acest lucru se întâmpla sigur de vreme ce sosesc confirmari, duplicate în cazul acesta) înseamna ca transferul nu este afectat de o congestie severa si prin urmare trecerea la slow start nu e (înca) necesara (slow start-ul elibereaza aproape complet canalul deoarece cwnd este resetat la dimensiunea unui singur segment).
Cei doi algoritmi pot fi implementati în felul urmator:
când se detecteaza trei confirmari consecutive identice se seteaza sstresh la jumatate din valoarea cwnd; se retransmite segmentul care s-a pierdut si se seteaza cwnd la valoarea egala cu sstresh plus dimensiunea a trei segmente (acest lucru va face ca algoritmul de incrementare a cwnd sa treaca la incrementare liniara)
la fiecare confirmare duplicata care mai soseste se incrementeaza cwnd se incrementeaza cu dimensiunea unui segment când înceteaza primirea de confirmari duplicate (segmentul retrimis a ajuns cu bine la receptor si s-a trimis o confirmare care acopera segmentul care se pierduse initial) cwnd este setat la valoarea sstresh Sindromul ``Silly Window''
Protocoalele bazate pe fereastra glisanta (cum este si TCP-ul) pot sa ajunga în situatia deloc fericita de trimite un numar mare de segmente mici în loc de segmente de dimensiune maxima. Acest tip de comportament este cunoscut sub numele de sindromul ``silly window''.
O modalitate prin care TCP-ul poate sa cada victima acestui tip de comportament este deschiderea de ferestre cu dimensiune foarte mica. O alta situatia nefericita este cea în care un transmitator este ``lacom'' si trimite date indiferent de cât de mica este fereastra (dupa cum vom vedea imediat uneori are sens si un astfel de comportament). Algoritmul de evitare a acestor neajunsuri este urmatorul:
un receptor nu trebuie sa anunte deschideri de ferestre mici. Mai exact nu se recomanda anuntarea unei incrementari a ferestrei mai mica decât dimensiunea unui segment (MSS) sau jumatate din buffer-ul aflat la dispozitia receptorului, oricare din ele e mai mica. un transmitator va trimite date doar în urmatoarele cazuri:
se poate trimite un segment întreg se poate trimite jumatate din dimensiunea celei mai mari ferestre pe care partenerul a publicat-o pâna acum toate datele trimise pâna acum au fost confirmate sau algoritmul Nagle este dezactivat si se trimit toate datele care sunt în buffer-ul de trimitere
Câteva justificari: cazul 2b trateaza cazul în care partenerul anunta ferestre mai mici decât dimensiunea unui segment iar cazul 2c impune conditiile respectarii algoritmului Nagle. dupa cum se vede daca algoritmul Nagle este activ si s-au acumulat destul date, mai exact cât dimensiunea unui segment, el va fi trimis chiar daca exista segmente neconfirmate. Pentru implementarea comportamentului impus de 2b un transmitator trebuie sa tina evidenta celei mai mari ferestre pe care partenerul a anuntat-o. Tinând seama ca dimensiunea acestor buffer-e nu se modifica acest mod de a încerca determinarea lor este suficient.
O alta problema legata tot de ferestre este cazul închiderii acesteia. Un mod în care s-ar putea anunta redeschiderea este trimiterea de catre receptor a unei confirmari (duplicat) care sa anunte redeschiderea la o anumita valoare a ferestrei. Deoarece acest pachet nu trebuie confirmat în mod special si s-ar putea sa se piarda se poate ajunge în situatia în care receptorul a anuntat redeschiderea ferestrei, segmentul s-a pierdut iar transmitatorul înca mai îl mai asteapta pentru a putea continua transferul. Rezolvarea la aceasta problema s-a facut prin impunerea unui alt comportament:
transmitatorul va trimite segmente cu dimensiunea datelor de un octet prin care sondeaza deschiderea ferestrei; intervalul la care se sondeaza redeschiderea ferestrei se dubleaza (exponential backoff); în RFC 793 dimensiunea maxima recomandata este de 2 minute însa în RFC 1122 se specifica ca maximul este acelasi cu cel din cazul retransmisiei (240 secunde)
receptorul trebuie sa refuze aceste pachete raspunzând cu segmente de confirmare care indica neprimirea octetului respectiv Observatie: timer-ul special necesar pentru implementare la transmitator a comportamentului de mai sus este cunoscut sub numele de ``TCP Persistent Timer''. Numele este justificat de faptul ca sondarea deschiderii se va face pâna când fie fereastra se deschide, fie conexiunea se întrerupe.
TCP Keepalive Timer Un lucru interesant despre TCP este faptul ca daca nivelele superioare nu comunica nimic între ele pentru o perioada lunga atunci nici un segment nu se v-a transfera. Acest lucru este de fapt perfect rezonabil de vreme de TCP-ul este de fapt un fel de contract cu care cei doi parteneri au fost de acord din momentul în care au trecut cu succes de faza stabilirii legaturii. Daca nivelurile inferioare (retea/IP, fizic) devin temporar indisponibile cât tip cei doi nu vor sa comunice atunci acest lucru nu va perturba în nici un fel activitatea si acest lucru este acceptabil. Problemele încep sa apara în momentul în care cei doi doresc sa comunice si nivelele inferioare nu mai permit acest lucru. Evident ca cel care va dori sa comunice ceva va detecta întreruperea legaturii si va închide conexiunea. Ce se întâmpla însa daca celalalt capat nu are nimic de comunicat (de exemplu este un server care ofera anumite servicii)? Pentru el legatura va fi în continuare activa si în general anumite resurse vor fi rezervate pentru aceasta. Rezolvarea acestei situatii este data de introducerea unei mecanism de sondare a starii legaturii pe baza unui timer (TCP Keepalive Timer) care se declanseaza din doua în doua ore. La fiecare expirare a timer-ului se trimite un segment fara date care confirma datele primite pâna atunci. Raspunsul care trebuie primit este tot un segment fara date care confirma datele primite de partener (practic o re-publicare a starii celor doi parteneri). Daca raspunsul nu este primit timp de 75 secunde atunci segmentul va fi retrimis. Daca dupa 10 astfel de încercari tot nu s-a primit nici un raspuns atunci conexiunea se va considera terminata si se va anunta nivelul superior asupra acestui lucru.
Observatii:
daca o statie primeste segmente de keepalive despre conexiuni care nu mai sunt active (de exemplu a fost resetat) atunci va raspunde cu segmente de reset (acesta e un procedeu standard); RFC 1122 specifica ca facilitatea de keepalive trebuie activata în mod explicit.
Fragmentarea pachetelor UDP
Deoarece UDP-ul este un serviciu fara conexiune toate datele pe care le primeste de la nivelul superior sunt încapsulate într-o singura datagrama UDP care apoi va forma un pachet IP. Daca pachetul IP astfel obtinut este prea mare atunci mecanismele IP de fragmentare îl vor sparge în bucati. Exemplul urmator încearca sa studieze exact acest fenomen.
Pe masina athos ruleaza un server de UDP pe portul 50007. Pe o alta masina, frodo, aflata în reteaua locala este rulat un client care poate fi configurat sa trimita un pachet UDP de o anumita lungime. Pentru a putea observa ce se întâmpla pe athos este rulat tcpdump.
Deoarece MTU-ul pentru o retea Ethernet este în general 1500 si antetul IP plus cel UDP ocupa 20 + 8 = 28 octeti, o datagrama UDP de dimensiune 1472 ar trebui sa fie trimisa nefragmentata. Pentru siguranta, folosind clientul de pe athos, s-a trimis mai întâi o datagrama UDP cu 1471 octeti de date, si apoi înca una cu 1472. Pentru ambele tcpdump a indicat trimiterea lor fara fragmentare
18:25:56.721144 frodo.noi.33274 > athos.noi.50007: udp 1471 (DF) (ttl 64, id 51481, len 1499) 18:25:59.846764 frodo.noi.33274 > athos.noi.50007: udp 1472 (DF) (ttl 64, id 51793, len 1500)
Stabilirea si eliberarea unei conexiuni TCP Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o masina (frodo) un server de TCP care va asculta pe portul 50007, va accepta fiecare conexiune primita si o va închide imediat. Clientul va rula pe o alta masina (alexandra) si dupa stabilirea conexiunii va închide la rândul sau conexiunea. Desi acest lucru ar trebui sa duca la o închidere simultana în realitate vom vedea ca are loc o închidere normala.
Iata ce arata un tcpdump rulat pe alexandra:
[numbers=left] 22:46:47.558868 alexandra.noi.34437 > frodo.noi.50007: SWE 2481641828:2481641828(0) win 5840 <mss 1460,sackOK,timestamp 10422756 0,nop,wscale 0> (DF) 22:46:47.559023 frodo.noi.50007 > alexandra.noi.34437: S 1579802286:1579802286(0) ack 2481641829 win 5792 <mss 1460,sackOK,timestamp 9639913 10422756,nop,wscale 0> (DF) 22:46:47.559081 alexandra.noi.34437 > frodo.noi.50007: . ack 1 win 5840 <nop,nop,timestamp 10422756 9639913> (DF) 22:46:47.559435 frodo.noi.50007 > alexandra.noi.34437: F 1:1(0) ack 1 win 5792 <nop,nop,timestamp 9639913 10422756> (DF) 22:46:47.560243 alexandra.noi.34437 > frodo.noi.50007: F 1:1(0) ack 2 win 5840 <nop,nop,timestamp 10422756 9639913> (DF) 22:46:47.560332 frodo.noi.50007 > alexandra.noi.34437: . ack 2 win 5792 <nop,nop,timestamp 9639913 10422756> (DF)
Liniile 1-2 reprezinta segmentul de SYN trimis de clientul de pe alexandra. Numarul de secventa este 2481641828, dimensiunea datelor efective este 0, flag-ul de ACK nu este setat, dimensiunea ferestrei este de 5840 octeti (aceasta corespunde spatiului ocupat de 4 segmente TCP continând fiecare 1460 octeti de date), dimensiunea maxima a unui segment (MSS) este de 1460 octeti (aceasta dimensiune este justificata de faptul ca într-un frame Ethernet nu se pot trimite mai mult de 1500 octeti si antetul IP + TCP ocupa 40 de octeti). Alte informatii pe care acest prim segment le contine: statia este capabila de a lucra cu notificari explicite referitoare la congestie (prezenta flagurilor WE indica acest lucru; W corespunde flag-ului TCP Congestion Window Reduced iar E ECN-Echo; ECN este acronimul de la Explicit Congestion Notification), cu confirmari selective (sackOK), cu marcaje de timp (timestamp) si cu scalari de ferestre (wscale).
Raspunsul (liniile 3-4) trimis de server-ul (frodo) confirma primirea segmentului (ack 2481641829) de deschidere de conexiune si isi publica si el informatiile legate de fereastra, MSS, timestamp si scalari ale dimensiunii ferestrei. În plus faptul ca flag-ul ECN-Echo nu este setat (E ar fi trebuit sa apara lânga S) indica faptul ca sistemul nu este capabil de ECN.
Liniile 5-6 reprezinta ultimul pas din secventa de initializare: confirmarea de catre client a segmentului trimis de server. Se poate observa ca de aici încolo tcpdump-ul afiseaza valori relative pentru numere de secventa si cele de confirmare.
Mai departe (liniile 7-8) frodo cere închiderea conxiunii (este setat flag-ul de FYN) prin trimiterea unui segment care nu contine date dar are un nou numar de secventa (e nevoie de asa ceva pentru ca partenerul sa poata confirma primirea acestui segment). alexandra raspunde (liniile 9-10) cu un segment care confirma primirea segmentului de la frodo si anunta terminarea conexiunii si din capatul lui. Dupa ce alexandra confirma primirea segmentului cele ambele statii considera dialogul încheiat.
Transferul de date TCP În conditii similare cu experimentul precedent vom încerca sa observam modul în care are loc un transfer simplu de date. Serverul va rula pe frodo si se va comporta ca un reflector: dupa stabilirea conexiunii asteapta primirea unor date pe care apoi le trimite înapoi la destinatie. Clientul va rula pe alexandra si dupa stabiliea conexiunii va trimite 8 octeti de date, va astepta raspunsul si apoi va închide conexiunea.
Un tcpdump rulat pe alexandra arata urmatoarele:
[numbers=left] 21:09:47.449182 alexandra.noi.35455 > frodo.noi.50007: SWE 3531138850:3531138850(0) win 5840 <mss 1460,sackOK,timestamp 14016045 0,nop,wscale 0> (DF) 21:09:47.449326 frodo.noi.50007 > alexandra.noi.35455: S 2833284198:2833284198(0) ack 3531138851 win 5792 <mss 1460,sackOK,timestamp 13950430 14016045,nop,wscale 0> (DF) 21:09:47.449374 alexandra.noi.35455 > frodo.noi.50007: . ack 1 win 5840 <nop,nop,timestamp 14016045 13950430> (DF) 21:09:47.449924 alexandra.noi.35455 > frodo.noi.50007: P 1:9(8) ack 1 win 5840 <nop,nop,timestamp 14016045 13950430> (DF) 21:09:47.450025 frodo.noi.50007 > alexandra.noi.35455: . ack 9 win 5792 <nop,nop,timestamp 13950430 14016045> (DF) 21:09:47.450145 frodo.noi.50007 > alexandra.noi.35455: P 1:9(8) ack 9 win 5792 <nop,nop,timestamp 13950430 14016045> (DF) 21:09:47.450161 alexandra.noi.35455 > frodo.noi.50007: . ack 9 win 5840 <nop,nop,timestamp 14016045 13950430> (DF) 21:09:47.450487 alexandra.noi.35455 > frodo.noi.50007: F 9:9(0) ack 9 win 5840 <nop,nop,timestamp 14016045 13950430> (DF) 21:09:47.450660 frodo.noi.50007 > alexandra.noi.35455: F 9:9(0) ack 10 win 5792 <nop,nop,timestamp 13950431 14016045> (DF) 21:09:47.450691 alexandra.noi.35455 > frodo.noi.50007: . ack 10 win 5840 <nop,nop,timestamp 14016045 13950431> (DF)
Primele trei segmente (liniile 1-6) reprezinta o deshidere identica cu cea pe care am studiat-o în cazul precedent. Segmentul care apare pe liniile 7-8 reprezinta cei 8 octeti de date care se doreau transferati. Deoarece segmentul contine toate datele flagul de PUSH este activat. Dupa ce datele au fost receptionate la server acesta genereaza un segment fara date (liniile 9-10) si apoi le trimite înapoi (liniile 10-11). Clientul care le primeste raspunde cu un segment de confirmare (liniile 13-14) . Mai departe urmeaza o închidere similara cu cea din exemplu precedent(liniile 15-20).
O observatie care se poate face pe baza afisarii furnizate de tcpdump e ca mecanismul de întârziere a confirmarilor nu a fost activ. Daca ar fi fost activ atunci confirmarea din segmentul de pe liniile 13-14 ar fi trebui sa faca parte din segmentul de date care urmeaza imediat (liniile 15-16). O posibila explicatie e ca frodo e înca în portiunea de slow start în care nici o confirmare nu e întarziata pentru a deschide cât mai repede fereastra de congestie.
La o dimensiune de 1473 ar trebui ca trimiterea sa genereze doua pachete IP: unul care sa contina primii antetul UDP plus primii 1472 octeti de date si înca un pachet IP care contine un singur octet. Iata ce indica tcpdump-ul:
18:26:05.705813 frodo.noi > athos.noi: udp (frag 36274:1@1480) (ttl 64, len 21) 18:26:05.706116 frodo.noi.33274 > athos.noi.50007: udp 1473 (frag 36274:1480@0+) (ttl 64, len 1500)
Intr-adevar au fost generate doua pachete IP:
primul contine doar un singur octet de date si reprezinta ultimul fragment (bitul de more fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest lucru) care a fost sparta în bucati; deplasamentul octetului primit in datagrama originala este 1480;
al doilea pachet este primul fragment din datagrama UDP si contine antetul UDP (din cauza asta datele efective ocupa doar 1480 octeti); deplasamentul este 0 si bitul de more fragments este setat (acest lucru este indicat de semnul ``+'' de dupa deplasament) Dupa cum se poate observa ambele pachete poarta acelasi numar de identificare (36274). Acest lucru împreuna cu informatiile date de flag-ul more fragments permite reconstructia la destinatie a datagramei UDP originale. O problema a acestui mod de fragmentare e ca în cazul pierderii unui fragment întreaga datagrama va fi compromisa si va trebui retrimisa în întregime. Ce se va întâmpla daca vom încerca sa trimitem un datagrama UDP suficient de mare pentru a necesita spargerea în trei bucati? Iata mai jos un transfer de 2973 de octeti:
13:21:08.251495 frodo.noi > athos.noi: udp (frag 23522:1@2960) (ttl 64, len 21) 13:21:08.251795 frodo.noi > athos.noi: udp (frag 23522:1480@1480+) (ttl 64, len 1500) 13:21:08.251935 frodo.noi.32843 > athos.noi.50007: udp 2953 (frag 23522:1480@0+) (ttl 64, len 1500)
Dupa cum se poate observa trimiterea în ordine inversa este o caracteristica a sistemului pe care am testat.
O datagrama de dimesiune si mai mare (16273) confirma acest lucru:
13:21:52.266391 frodo.noi > athos.noi: udp (frag 23523:1@16280) (ttl 64, len 21) 13:21:52.266697 frodo.noi > athos.noi: udp (frag 23523:1480@14800+) (ttl 64, len 1500) 13:21:52.266843 frodo.noi > athos.noi: udp (frag 23523:1480@13320+) (ttl 64, len 1500) 13:21:52.266976 frodo.noi > athos.noi: udp (frag 23523:1480@11840+) (ttl 64, len 1500) 13:21:52.267114 frodo.noi > athos.noi: udp (frag 23523:1480@10360+) (ttl 64, len 1500) 13:21:52.267253 frodo.noi > athos.noi: udp (frag 23523:1480@8880+) (ttl 64, len 1500) 13:21:52.267391 frodo.noi > athos.noi: udp (frag 23523:1480@7400+) (ttl 64, len 1500) 13:21:52.267539 frodo.noi > athos.noi: udp (frag 23523:1480@5920+) (ttl 64, len 1500) 13:21:52.267678 frodo.noi > athos.noi: udp (frag 23523:1480@4440+) (ttl 64, len 1500) 13:21:52.267819 frodo.noi > athos.noi: udp (frag 23523:1480@2960+) (ttl 64, len 1500) 13:21:52.267956 frodo.noi > athos.noi: udp (frag 23523:1480@1480+) (ttl 64, len 1500) 13:21:52.268096 frodo.noi.32843 > athos.noi.50007: udp 16273 (frag 23523:1480@0+) (ttl 64, len 1500)
|
|