Mihai Sprinceana
Un forum de programare cu de toate. Va astept sa va inscrieti si sa deveniti moderatori. Oricine este binevenit aici sa se inscrie si sa aiba acces la informatie free! Fiecare este liber sa adauge proiecte programe free etc. Ajutati acest forum sa devina o comunitate puternica unde fiecare invata de la fiecare! Tot ce trebuie sa faceti este sa va inregistrati si fiecare contributie se poate dovedi utila in timp! Forumul este free informatia free dk aveti timp liber ajutati si pe ceilalti si invatati si voi in acelasi timp! Haideti sa facem ceva pt.a ne ajuta intre noi! Cititi regulament postare forum inainte de a posta!
Lista Forumurilor Pe Tematici
Mihai Sprinceana | Inregistrare | Login

POZE MIHAI SPRINCEANA

Nu sunteti logat.
Nou pe simpatie:
swiss_virginia
Femeie
25 ani
Cluj
cauta Barbat
27 - 54 ani
Mihai Sprinceana / Retele / Protocoale TCP/IP la nivelul transport Moderat de Houssey, andreeamp, costin1920, fireratbat, ozzywz4rd, profu.info, sade5000
Autor
Mesaj Pagini: 1
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)















pus acum 17 ani
   
Pagini: 1  

Mergi la