+ All Categories

udp tcp

Date post: 11-Aug-2015
Category:
Upload: seitancalin
View: 68 times
Download: 6 times
Share this document with a friend
24
Reţele locale de calculatoare Ghid de laborator Cuprins 7 Protocoale TCP/IP la nivelul transport o 1 UDP 1 Caracteristici UDP 2 Formatul pachetelor UDP o 2 TCP 1 Caracteristici TCP 2 Formatul pachetelor TCP 3 Iniţierea şi terminarea unei conexiuni TCP Protocolul de iniţiere Protocolul de terminare Diagrama de stări 4 Controlul fluxului Întârzierea confirmărilor Algoritmul Nagle Fereastra glisantă Slow start Retransmission Timeout (RTO) şi Round-Trip Time (RTT) Evitarea congestiei Fast Retransmission, Fast Recovery Sindromul ``Silly Window'' TCP Keepalive Timer o 3 Studii de caz 1 Fragmentarea pachetelor UDP 2 Stabilirea şi eliberarea unei conexiuni TCP 3 Transferul de date TCP Bibliografie About this document ... Cuprins 7 Protocoale TCP/IP la nivelul transport o 1 UDP 1 Caracteristici UDP 2 Formatul pachetelor UDP o 2 TCP 1 Caracteristici TCP 2 Formatul pachetelor TCP 3 Iniţierea şi terminarea unei conexiuni TCP
Transcript
Page 1: udp tcp

Reţele locale de calculatoare

Ghid de laborator

Cuprins

7 Protocoale TCPIP la nivelul transport

o 1 UDP

1 Caracteristici UDP

2 Formatul pachetelor UDP

o 2 TCP

1 Caracteristici TCP

2 Formatul pachetelor TCP

3 Iniţierea şi terminarea unei conexiuni TCP

Protocolul de iniţiere

Protocolul de terminare

Diagrama de stări

4 Controlul fluxului

Icircntacircrzierea confirmărilor

Algoritmul Nagle

Fereastra glisantă

Slow start

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Evitarea congestiei

Fast Retransmission Fast Recovery

Sindromul ``Silly Window

TCP Keepalive Timer

o 3 Studii de caz

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

Bibliografie

About this document

Cuprins

7 Protocoale TCPIP la nivelul transport

o 1 UDP

1 Caracteristici UDP

2 Formatul pachetelor UDP

o 2 TCP

1 Caracteristici TCP

2 Formatul pachetelor TCP

3 Iniţierea şi terminarea unei conexiuni TCP

4 Controlul fluxului

o 3 Studii de caz

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

Bibliografie

About this document

7 Protocoale TCPIP la nivelul transport

Subsections

1 UDP

o 1 Caracteristici UDP

o 2 Formatul pachetelor UDP

2 TCP

o 1 Caracteristici TCP

o 2 Formatul pachetelor TCP

o 3 Iniţierea şi terminarea unei conexiuni TCP

Protocolul de iniţiere

1 Deschiderea simultană

Protocolul de terminare

2 Terminarea simultană

3 Resetarea conexiunii

Diagrama de stări

o 4 Controlul fluxului

Icircntacircrzierea confirmărilor

Algoritmul Nagle

Fereastra glisantă

Slow start

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Evitarea congestiei

Fast Retransmission Fast Recovery

Sindromul ``Silly Window

TCP Keepalive Timer

3 Studii de caz

o 1 Fragmentarea pachetelor UDP

o 2 Stabilirea şi eliberarea unei conexiuni TCP

o 3 Transferul de date TCP

1 UDP

Subsections

1 Caracteristici UDP

2 Formatul pachetelor UDP

1 Caracteristici UDP

UDP (User Datagram Protocol) este un protocol de nivel transport construit special pentru a oferi

un serviciu de comunicare cacirct mai simplu peste IP Specificaţiile protocolului au fost publicate icircn

1980 icircn RFC-ul cu numărul 7681

Cacircteva caracteristici ale UDP-ului sunt

este un serviciu de tip datagramă cererile de trimitere de date primite de la nivelul

superior sunt tratate independent

comunicarea are loc fără stabilirea unei legături (conection-less) nu există mecanisme de

stabilire şi terminare a unei conexiuni deoarece toate datele sunt trimise icircn cadrul unui

singur pachet IP care eventual va fi supus fragmentării

nu se garantează ajungerea ala destinaţie a datelor (best effort) ajungerea la destinaţie nu

este anunţată sursei

datele transportate sunt protejate de o sumă de control (introdusă ca opţională iniţial ea

este trecută ca necesară(must) icircn RFC 1122 care stabileşte modul de comportare al

clienţilor icircn Internet)

overhead-ul introdus este minim doar 8 octeţi

Cacircteva utilizări tipice ale UDP-ului

servicii de rezolvare a numelor (DNS) deoarece icircntrebările şi răspunsurile 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 fişiere (NFS) deoarece acest tip de aplicaţii sunt icircn general rulate icircn reţele

locale cu performanţe ridicate care nu necesită mecanismele TCP

managementul reţelei (SNMP)

protocoale de rutare (RIP)

Footnotes

7681

RFC 768 are nici mai mult nici mai puţin decacirct 3 pagini nu conţine cuprins dar are o listă

de 5 referinţe bibliografice

2 Formatul pachetelor UDP

Datagramele UDP sunt formate dintr-un antet (figura 71) urmat de datele care se doresc

transmise (dacă există)

Figura 71 Structura unei datagrame UDP

Antetul cuprinde

port sursă - 16 biţi

Icircmpreună cu adresa IP a sursei acest număr identifică icircn mod unic locul de unde a fost

trimis datagrama UDP

port destinaţie - 16 biţi

Icircmpreună cu adresa IP a destinaţiei acest număr identifică icircn mod unic destinaţia dorită

pentru datagrama UDP

lungimea pachetului UDP - 16 biţi

Lungimea minimă măsoară datagrama UDP cu tot cu antent şi prin urmare are o valoare

minimă de 8 octeţi

sumă de control - 16 biţi

Suma de control acoperă icircntreg pachetul UDP cacirct şi un pseudo antet de 12 octeţi format

din

adresa IP a sursei - 32 biţi

o adresa IP a destinaţiei - 32 biţi

8 biţi de zero pentru aliniere

numărul protocolului UDP (17) reprezentat pe 8 biţi

lungimea pachetului UDP - 16 biţi

Deoarece suma de control necesită icircn calculul ei un număr multiplu de 16 octeţi la

sfacircrşitul datelor se adaugă un număr potrivit de octeţi de zero Dacă suma este 0 atunci ea

va fi stocată ca 65535 (toţi biţii pe 1) Un 0 icircn cacircmpul de sumei de control indică faptul

că suma de control nu a fost calculată Observaţie chiar dacă un client are inhibat (icircn

mod explicit) calcului sumei de control el este obligat să verifice suma pachetelor care

sosesc şi au suma calculată

2 TCP

Subsections

1 Caracteristici TCP

2 Formatul pachetelor TCP

3 Iniţierea şi terminarea unei conexiuni TCP

o Protocolul de iniţiere

1 Deschiderea simultană

o Protocolul de terminare

2 Terminarea simultană

3 Resetarea conexiunii

o Diagrama de stări

4 Controlul fluxului

o Icircntacircrzierea confirmărilor

o Algoritmul Nagle

o Fereastra glisantă

o Slow start

o Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

o Evitarea congestiei

o Fast Retransmission Fast Recovery

o Sindromul ``Silly Window

o TCP Keepalive Timer

1 Caracteristici TCP

Deoarece protocolul IP este de tip datagramă utilizarea lui direct icircn aplicaţii care in general au

nevoie de conexiuni sigure este mult prea anevoioasă Din aceste motive peste IP a fost construit

un alt protocol TCP (transimission control protocol) care corectează aceste probleme Prima

definire se găseşte icircn RFC-ul cu numărul 793 şi datează din septembrie 1981 Din cauza deselor

congestii apărute icircn 1986 algoritmul care stă la baza TCP-ului este reanalizat şi icircn octombrie

1989 icircn RFC-ul cu numărul 1122 este publicată o nouă specificare mult mai eficientă şi

neambiguă a TCP-ului Noi probleme legate de viteze mari sunt tratate icircn RFC-ul 1323 iar icircn

2018 TCP-ul este extins pentru a permite confirmările selective (selective acknowledge) Seria

de RFC-urie fundamentale este icircncheiată de apariţia icircn 1989 a RFC-ului cu numărul 2581 Icircn el

se specifică foarte strict comportamentul care este permis pentru o implementare de TCP

Alături de protocolul UDP TCP se situează pe nivelul transport icircn ierarhia de protocoale deci

icircntre nivelul aplicaţie şi nivelul reţea Dar cu toate că se bazează pe acelaşi protocol (IP) ca şi

UDP TCP furnizează către nivelul aplicaţie cu totul alt tip de servicii servicii orientate-

conexiune sigure de tip flux de octeţi

Termenul de orientat-conexiune presupune că icircntre cele două aplicaţii care comunică utilizacircnd

TCP trebuie să se stabilească o conexiune TCP icircnainte ca transferul de date să aibă loc Această

conexiune nu este efectiv una fizică ci virtuală asemănător cum se icircntacircmplă icircn sistemul de

telefonie clasică cineva formează un număr şi abia icircn momentul icircn care cealaltă persoană

răspunde se poate icircncepe conversaţia Fiind o conexiune host-la-host nu există noţiunile de

broadcast sau multicast

Transferul sigur de date este asigurat icircn următorul mod

Datele sunt icircmpărţite icircn bucăţi a căror dimensiune optimă e determinată de TCP spre

deosebire de UDP care trimite datagrame UDP corespunzătoare cu dimensiunea datelor

primite de la nivelul aplicaţie Unitatea de date trimisă de TCP către nivelul reţea poartă

numele de segment

Cacircnd TCP trimite un segment porneşte un timer şi dacă nu se primeşte confirmarea

segmentului respectiv icircntr-un anumit timp icircl retransmite

Icircn momentul icircn care se primeşte un segment TCP trimite o confirmare (din motive de

eficienţă aceasta poate fi amacircnată un anumit interval de timp)

Icircn headerul TCP este menţinută o sumă de control pentru detectarea modificărilor icircn date

Dacă se recepţionează un segment corupt TCP icircl ignoră urmacircnd să fie retransmis datorită

neprimirii confirmării

Deoarece segmentele TCP sunt transmise mai departe icircncapsulate icircn datagrame IP iar

acestea pot ajunge icircn orice ordine segmentele TCP pot ajunge icircn altă ordine decacirct cea icircn

care au fost trimise De aceea la destinaţie TCP-ul trebuie să se folosească de numere de

secvenţă pentru a reordona eventual segmentele icircnainte de a le livra către nivelul

aplicaţie De asemenea TCP trebuie să asigure ignorarea duplicatelor

TCP asigură controlul fluxului icircn condiţiile icircn care viteza de trimitere a datelor de la sursă

poate fi mult prea mare decacirct capacitatea de prelucrare de la destinaţie

Serviciul oferit de TCP este de tip flux de octeţi deoarece oferă garanţii că fluxul de date trimis

de sursă va fi livrat fără modificări la destinaţie Comparativ UDP-ul produce pentru fiecare

transfer cerut de nivelul aplicaţie un pachet IP (care ulterior poate fi supus fragmentării) care

dacă ajunge la destinaţie corect va fi livrat direct nivelului aplicaţie fără a garanta icircn vreun fel

ordinea

2 Formatul pachetelor TCP

Pachetele de date transmise de TCP segmentele sunt formate dintr-un antet (figura 72) de 20

octeţi urmat de datele primite de la nivelul aplicaţie Antetul poate uneori conţine şi o serie de

opţiuni caz icircn care poate ajunge la 60 octeţi

Figura 72 Structura unui segment TCP

Antetul unui segment TCP cuprinde

port sursă - 16 biţi pentru specificarea portului aplicaţiei transmiţătoare

port destinaţie - 16 biţi pentru specificarea portului aplicaţiei ce recepţionează segmentul

TCP

Aceste două porturi icircmpreună cu adresele ale sursei şi destinaţiei conţinute icircn antet-ul IP

identifică icircn mod unic conexiunea Pentru o pereche formată dintr-o adresă IP şi un port

se foloseşte adesea denumirea de socket (denumire introdusă icircn specificaţiile iniţiale ale

protocolului TCP icircn RFC 793)

număr de secvenţă - 32 biţi

Pentru a asigura un serviciu de tip flux de octeţi TCP numerotează fiecare octet de date

utilizacircnd un număr de secvenţă Numărul de secvenţă din cadrul antetului TCP specifică

destinaţiei care este primul octet din fluxul trimis La iniţierea unei conexiuni se setează

flag-ul SYN şi se alege aleator un număr de secvenţă de icircnceput utilizacircnd un generator de

numere de secvenţă ISN (Initial sequence number) Numărul de secvenţă al primului

octet de date va fi numărul generat ISN plus 1 deoarece pachetul de iniţiere (cu SYN

setat) consumă şi el un număr de secvenţă Se va vedea mai departe că şi flag-ul de

terminare a conexiunii FIN consumă şi el un număr de secvenţă

confirmare - 32 biţi

Reprezintă numărul de secvenţă al octetului de date pe care transmiţătorul confirmării se

aşteaptă să-l primească Astfel dacă s-a recepţionat octetul cu numărul de secvenţă x (icircn

numerotaţia sursei) pachetul de confirmare va avea flag-ul ACK setat şi va conţine

numărul de confirmare x + 1 Trimiterea unui ACK nu consumă un număr de secvenţă

deoarece atacirct acest cacircmp cacirct şi flag-ul ACK fac parte din antet şi după stabilirea

conexiunii ambele cacircmpuri devin active Acest mecanism nu permite confirmări selective

pentru că numărul de secvenţă specifică pacircnă unde s-au recepţionat date De exemplu

dacă la destinaţie au ajuns octeţii 1-1024 şi următorul segment primit conţine octeţii

2049-3072 nu se poate trimite confirmare pentru cel de-al doilea segment deci

confirmarea va cuprinde numărul de secvenţă 1025

lungimea antetului - 4 biţi

Specifică dimensiunea antetului ca număr de cuvinte de 32 de biţi (4 octeţi) Antetul

poate avea icircntre 20 şi 60 de octeţi deci valoarea acestui cacircmp va fi icircntre 5 (5 x 4 = 20

octeţi) şi 15 (15 x 4 = 60)

6 biţi rezervaţi pentru utilizări viitoare

6 biţi de control reprezentacircnd următoarele flag-uri ce pot fi setate simultan

o URG - cacircmpul urgent pointer este valid

o ACK - cacircmpul de confirmare este valid

o PSH - destinaţia trebuie să trimită datele către nivelul aplicaţie cacirct mai devreme

o RST - se doreşte resetarea conexiunii

o SYN - iniţierea conexiunii

o FIN - icircnchiderea conexiunii

dimensiunea ferestrei - 16 biţi

Reprezintă numărul de octeţi (icircncepacircnd cu numărul de secvenţă conţinut icircn cacircmpul de

confirmare) pe care destinaţia e dispusă să-l primească Este limitat la 65535 octeţi dar

cu toate că pare o limită destul de mare există situaţii cacircnd se doresc valori mult mai

mari Icircn acest scop se folosesc nişte opţiuni speciale descrise ceva mai tacircrziu care permit

scalarea ferestrei

suma de control - 16 biţi

Această sumă de control acoperă icircntregul segment TCP (atacirct datele cacirct şi antetul TCP) şi

spre deosebire de UDP este obligatoriu să fie completat de transmiţător şi verificat de

receptor Dar ca şi icircn cazul UDP-ului la calculul sumei de control se ia in considerare şi

o zona specială de 12 octeţi ce cuprinde pentru re-verificare cacircmpuri din antetul IP

(adresa IP a sursei şi a destinaţiei)[aici tre sa vina o referire la poza cu pseudo-antetu]

După adăugarea acestui pseudo-antet datele se icircmpart icircn cuvinte de 16 biţi icircn vederea

calculării sumei de control adăugacircndu-se eventual şi un octet de aliniere

urgent pointer - 16 biţi

Este utilizat pentru specificarea deplasamentului ultimului octet de date trimis icircn regim

urgent Astfel ultimul octet din secvenţa urgentă se obţine adunacircnd acest cacircmp la

numărul de secvenţă Ce icircnseamnă acest mod urgent de transmitere există situaţii icircn care

aplicaţiile vor să trimită date `neordonate` Să presupunem că aplicaţia a trimis către

nivelul transport o cantitate mare de date dar la un moment dat observă ceva icircn neregulă

şi doreşte să anuleze operaţia Dacă trimite o comandă de anulare aceasta va fi adăugată

la sfacircrşitul şirului de octeţi deci nu se va putea icircmpiedica ajungerea acestora la nivelul

aplicaţie de la receptor Activacircnd modul urgent datele urgente (comanda de anulare) vor

fi plasate la icircnceputul pachetului Aplicaţiile mai cunoscute care folosesc acest mod sunt

Telnet Rlogin şi FTP

opţiuni - pacircnă la 40 de octeţi (figura 73)

Cele mai utilizate opţiuni sunt

o Sfacircrşit de opţiuni (end of option) - 1 octet

Este utilizat pentru alinierea datelor conţinute icircn cacircmpul de opţiuni Nu poate fi

utilizat decacirct o singură dată marcacircndu-se astfel sfacircrşitul opţiunilor şi icircnceperea

datelor efective Dacă pentru alinierea la un cuvacircnt de 32 de biţi e nevoie de mai

mult de 1 byte se va utiliza opţiunea no operation Orice apare după această

opţiune pacircnă la icircnceputul cuvacircntului următor de 32 de biţi e ignorat

o no operation - 1 octet

Utilizat pentru alinierea la cuvinte de 32 de biţi

o Dimensiunea maximă a segmentului (Maximum Segment Size (MSS)) - 16 biţi

Icircn ciuda denumirii defineşte lungimea maximă a datelor nu dimensiunea

icircntregului segment Poate lua valori icircntre 0 şi 65535 valoarea implicită fiind 536

Această opţiune e valabilă doar icircn pachetele de iniţiere a conexiunii (cele cu flag-

ul SYN setat) fiecare parte făcacircnd cunoscută dimensiunea maximă a datelor

dispusă să le primească icircntr-un pachet Icircn principiu cu cacirct această valoarea e mai

mare e mai bine (deoarece se recuperează din spaţiul ocupat de antetele TCP şi

IP) pacircnă cacircnd apare fragmentarea Valoarea maximă la care se poate seta este

MTU (Maximum Transfer Unit) minus dimensiunea antetului IP şi TCP (1460

octeţi icircn cazul Ethernet)

o Factor de scalare a ferestrei (Window scale factor) - 1 octet

Pentru situaţiile icircn care se doreşte utilizarea unei ferestre mai mare de 65535 bytes

se poate utiliza acest cacircmp pentru mărirea dimensiunii ferestrei Noua dimensiune

va fi Chiar dacă

factorul de scalare poate fi maxim 255 icircn cazul TCPIP el nu poate depăşi

valoarea 16 deoarece dimensiunea maximă a ferestrei nu poate fi mai mare decacirct

valoarea celui mai mare număr de secvenţă ( )

Acest factor se poate seta doar la iniţierea conexiunii Icircn timpul transferului de

date se poate modifica dimensiunea ferestrei dar factorul de scalare rămacircne

acelaşi Dacă cel care a iniţiat conexiunea a trimis icircn segmentul de iniţiere şi acest

factor dar icircn pachetul cu ACK destinatarul nu şi-a trimis şi el factorul atunci se la

considera 0 icircn ambele direcţii Invers dacă cel care solicită deschiderea

conexiunii nu setează factorul destinaţia nu va putea seta factorul de scalare

o Timestamp - 10 octeţi

Utilizat pentru reţinerea timpului icircn vederea calculării RTT (Round Trip Time)

Cacircmpul timestamp e completat de sursă icircn momentul trimiterii segmentului La

destinaţie valoarea este reţinută şi copiată icircn cacircmpul timestamp echo reply al

pachetului cu confirmarea RTT-ul este calculat de sursă făcacircnd diferenţa dintre

timpul curent şi această valoare

Figura Opţiuni TCP

3 Iniţierea şi terminarea unei conexiuni TCP

TCP este un protocol orientat conexiune deci presupune stabilirea unei căi virtuale icircntre sursă şi

destinaţie

Subsections

Protocolul de iniţiere

o 1 Deschiderea simultană

Protocolul de terminare

o 2 Terminarea simultană

o 3 Resetarea conexiunii

Diagrama de stări

Protocolul de iniţiere

Modul de transmisie icircn cazul protocolului TCP este full-duplex deci sunt transmise date

simultan icircn ambele direcţii Aceasta presupune că cel care iniţiază conexiunea trebuie să

primească aprobarea celuilalt capăt icircnainte de icircnceperea transferului de date sursa icircşi anunţă

intenţia de a iniţia o conexiune destinaţia trimite un pachet cu confirmarea cererii şi un pachet de

iniţiere a conexiunii de la el la sursă iar apoi sursa confirmă cererea primită de la destinaţie Paşii

2 şi 3 pot fi realizaţi prin trimiterea unui singur pachet de aceea protocolul de iniţiere este

cunoscut sub numele de three-way handshake

Icircn cadrul protocolului de iniţiere există 2 tipuri de cereri de iniţiere cerere activă (active open)

iniţiată de clientul ce doreşte să stabilească conexiunea cu serverul şi cerere pasivă (passive

open) din partea serverului

Cei 3 paşi sunt

1 Clientul trimite un segment cu flag-ul SYN setat şi care conţine portul sursă portul de la

destinaţie şi numărul de secvenţă generat iniţial (ISN) de la care se vor numerota octeţii

de la client către server Opţional se pot stabili parametrii conexiunii prin setarea lungimii

maxime a segmentelor (MSS) dispus să le primească de la server factorului de scalare a

ferestrei Acest prim segment nu conţine nici un parametru de confirmare şi de asemenea

nu are rost să conţine să seteze dimensiunea ferestrei

2 Al doilea segment e trimis de server şi are un rol dublu confirmă segmentul primit de la

client prin setarea flag-ului ACK şi completează numărul de secvenţă cu numărul de

secvenţă primit plus 1 şi al doilea rol iniţializează conexiunea de la el către client prin

setarea flag-ului SYN şi generarea unui număr de secvenţă iniţial ce va fi folosit icircn

numerotarea octeţilor de la server spre client Pe lacircngă aceasta trebuie să conţină

dimensiunea ferestrei şi opţional poate seta factorul de scalare şi dimensiunea maximă a

segmentului acceptat

3 Clientul trimite un segment cu confirmarea cererii din partea serverului (ACK setat +

completează numărul confirmat cu numărul de secvenţa primit + 1) Ca şi icircn cazul

pasului 2 trebuie să seteze dimensiunea ferestrei Acest pachet poate conţine date

Subsections

1 Deschiderea simultană

1 Deschiderea simultană

Se poate icircntacircmpla ca uneori cele două capete care vor să comunice să icircncerce să stabilească

conexiunea simultan Icircn acest caz după ce fiecare a trimis segmentul de iniţiere (iniţiere activă)

ambele vor trimite un segment cu SYN + ACK şi se va stabili o singură conexiune nu două

Protocolul de terminare

Oricare dintre cele două părţi poate solicita icircnchiderea conexiunii dar conexiunea fiind full-

duplex transferul de date icircn celălalt sens poate continua (această situaţie e denumită half-close)

O icircnchidere completă a unei conexiuni TCP presupune următorii paşi

1 Clientul trimite un segment cu flag-ul FIN activat solicitacircnd icircnchiderea conexiunii

2 Serverul trimite un segment ACK confirmacircnd primirea cererea Numărul de confirmare

se completează normal ca numărul de secvenţă primit + 1

3 Serverul continuă să trimită date către client şi cacircnd doreşte să icircnchidă şi el conexiunea

trimite un segment cu FIN activat

4 Clientul trimite un pachet ACK confirmacircnd icircnchiderea conexiunii

Cel care iniţiază primul procedura de icircnchidere (trimite primul FIN) realizează o icircnchidere activă

(active close) iar celălalt capăt o icircnchidere pasivă (passive close) Icircn mod normal cel care

realizează iniţierea activă va fi primul ce va trimite FIN dar oricare dintre cei doi poate icircnchide

activ conexiunea

Subsections

2 Terminarea simultană

3 Resetarea conexiunii

2 Terminarea simultană

Icircn mod similar cu deschiderea simultană există posibilitatea ca ambele capete ale conexiunii TCP

să iniţieze simultan procedura de icircnchidere a conexiunii Icircn acest caz ambele părţi vor trimite

FIN şi vor aştepta primirea unui ACK Icircn continuare fiecare va primi cererea de terminare şi va

trimite ACK Se observă că numărul de segmente transferate pentru realizarea icircnchiderii

conexiunii (4 segmente) este acelaşi ca la terminarea normală

3 Resetarea conexiunii

Există situaţii icircn care TCP doreşte resetarea conexiunii De exemplu dacă se solicită iniţierea

unei conexiuni la un port inexistent Icircn acest caz cealaltă parte va trimite un segment cu bitul

RST setat pentru a anula solicitarea O altă situaţie este atunci cacircnd se constată că celalalt capăt

al conexiunii nu răspunde un anumit timp (timeout)

Diagrama de stări

Toate evenimentele ce au loc icircn timpul stabilirii conexiunii transferului şi icircnchiderii conexiunii

pot fi rezumate printr-un automat finit cunoscut sub numele de diagrama de stări După cum

chiar numele sugerează este o maşină cu un număr limitat de stări O stare este păstrată pacircnă icircn

momentul apariţiei unui eveniment moment icircn care se poate trece icircn altă stare şisau efectua o

acţiune

Aceste stări posibile sunt (denumirile sunt asemănătoare cu cele utilizate de netstat) cele din

tabelul 71

Tabela Stările diagramei de stări TCP

Stare Descriere

CLOSED Nu există conexiune

LISTEN Serverul aşteaptă cereri de la clienţi

SYN_SENT Cerere de iniţiere (activă) a conexiunii Se

aşteaptă confirmarea

SYN_RCVD S-a primit o cerere de iniţiere conexiune

ESTABLISHED S-a stabilit conexiunea

FIN_WAIT_1 Aplicaţia a solicitat icircnchiderea conexiunii

FIN_WAIT_2 Serverul a acceptat icircnchiderea conexiunii

CLOSING Ambele părţi solicită simultan icircnchiderea

conexiunii

TIME_WAIT Conexiune icircnchisă dar se aşteaptă ca

pachetele retransmise să dispară

CLOSE_WAIT Serverul aşteaptă icircnchiderea dinspre partea

aplicaţiei

LAST_ACK Serverul a icircnchis conexiunea Aşteaptă

ultima confirmare

Icircn diagrama ilustrată icircn figura 74 putem observa 3 tipuri de tranziţii icircntre cele 11 stări tranziţii

ce corespund unei funcţionări normale pentru client (linii normale continue) pentru server (linii

normale icircntrerupte) şi tranziţii pentru situaţii nestandard (linii subţiri continue)

O comportarea normală pentru client presupune parcurgerea următoarelor stări CLOSED

SYN_SEND ESTABLISHED FIN_WAY_1 FIN_WAY_2 TIME_WAIT

Iniţial clientul TCP se află icircn starea CLOSED

Aşteptacircnd icircn starea CLOSED clientul poate primi de la aplicaţie o cerere de iniţiere

activă a unei conexiuni Trimite un segment SYN şi trece icircn starea SYN_SENT

Icircn starea SYN_SENT clientul aşteaptă de la server un segment ACK+SYN după care

trimite un ACK şi trece icircn starea ESTABLISHED Din acest moment poate icircncepe

transferul efectiv de date Clientul va rămacircne icircn această stare cacirct timp are de trimisprimit

date

Aflat icircn această stare clientul TCP poate primi din partea aplicaţiei o cerere de icircnchidere a

conexiunii Icircn acest caz va trimit un segment FIN şi trece icircn starea FIN_WAIT_1

Icircn această stare clientul aşteaptă ACK din partea serverului După ce-l primeşte

conexiunea icircntr-un sens se va icircnchide şi clientul trece icircn starea FIN_WAIT_2

Starea FIN_WAIT_2 durează pacircnă cacircnd primeşte cererea de icircnchidere a conexiunii FIN

din partea serverului Trimite ACK şi va trece icircn starea TIME_WAIT

Icircn această stare se va porni un timer cu valoarea setată la dublul timpului de viaţă estimat

pentru un segment de lungime maximă MSL (Maximum Segment Lifetime) Acest timer

permite retransmiterea ACK-ului icircn cazul icircn care acesta se pierde (celălalt capăt va da

timeout şi va retransmite segmentul FIN) Icircn tot acest time cei doi sockeţi (de la client şi

server) nu vor putea fi reutilizaţi Totodată pachetele icircntacircrziate care sosesc icircn această

perioadă sunt ignorate După expirarea acestui timer clientul revine icircn starea iniţială

CLOSED

Din punctul de vedere al unui server o comportare standard parcurge următoarele stări

CLOSED LISTEN SYN_RCVD ESTABLISHED CLOSE_WAIT şi LAST_ACK

Iniţial serverul TCP se află icircn starea CLOSED

Icircn această stare poate primi de la aplicaţia server o cerere de iniţiere activă şi trece icircn

starea LISTEN

Aflat icircn starea LISTEN serverului TCP poate recepţiona un segment SYN de la un client

TCP Icircn acest caz va trimite ACK+SYN şi va trece icircn starea SYN_RCVD

Icircn această stare serverul aşteaptă primirea confirmării de la client moment icircn care

conexiunea e stabilită icircn ambele sensuri şi se poate icircncepe transferul de date (starea

ESTABLISHED)

Clientul TCP poate solicita icircnchiderea conexiunii trimiţacircnd un segment FIN către server

Icircn acest caz serverul TCP trimite confirmarea şi trece icircn starea CLOSE_WAIT

Icircn această stare serverul aşteaptă să primească din partea programului server icircnchiderea

conexiunii moment icircn care va trimite către client un segment FIN şi trece icircn starea

LAST_ACK

Serverul aşteaptă primirea ultimei confirmări de la client după care revine icircn starea

CLOSED

Atacirct serverul cacirct şi clientul TCP se pot afla icircn oricare din cele 11 stări ale diagramei

Figura Diagrama de stări pentru TCP

4 Controlul fluxului

Dacă icircncă de la icircnceput s-a reuşit stabilirea formatului unui pachet TCP şi a modulului icircn care

trebuie să se facă icircnchiderea şi deschiderea unei conexiuni nu acelaşi lucru se poate spune şi

despre modul icircn care ar trebui să se realizeze controlul fluxului Ţinacircnd seama icircnsă că din 1989

(de cacircnd datează RFC-ul 2581 cel despre care am menţionat că specifică icircn mod clar modul icircn

care trebuie să se comporte o implementare de TCP) TCP-ul a rămas neschimbat putem să icircl

considerăm un rezultat important al domeniului reţelor de calculatoare

Icircn cele ce urmează vom icircnţelege prin controlul fluxului totalitatea algoritmilor care permit

atingerea unei viteze de transfer punct-la-punct cacirct mai mare pentru toate conexiunile existente

Icircn principal aceşti algoritmi stabilesc modul icircn care segmentele şi confirmările trebuie trimise şi

ce acţiuni trebuie executate icircn situaţiile icircn care răspunsurile aşteptate de la celălalt capăt icircntacircrzie

să vină

Subsections

Icircntacircrzierea confirmărilor

Algoritmul Nagle

Fereastra glisantă

Slow start

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Evitarea congestiei

Fast Retransmission Fast Recovery

Sindromul ``Silly Window

TCP Keepalive Timer

Icircntacircrzierea confirmărilor

O modalitate simplă de generare a confirmărilor este de a trimite cacircte una pentru fiecare segment

primit Această politică prezintă avantajul de a face comunicaţia self-clocking icircnsă este

ineficientă dacă segmentele care nu conţin decacirct confirmări sunt urmate la scurtă distanţă (cacircteva

zeci de milisecunde) de segmente ce conţin date efective Pentru a evita această situaţie se

procedează2 la icircntacircrzierea (200ms este o valoare uzuală icircn RFC 1122 se specifică o valoare

maximă de 500ms) a segmentelor care conţin doar confirmări Această strategie face posibil ca

un răspuns generat de primirea unor date să plece sper celălalt capăt icircn acelaşi segment cu

confirmarea

Observaţie deoarece este dificil de menţinut timere pentru fiecare confirmare diferenţa de

200ms este calculată de un timer global Din acest motiv modul efectiv de comportare poate fi

descris şi icircn felul următor cacircnd un segment nu conţine decacirct o confirmare el este pus icircntr-o

coadă ce va fi inspectată de un proces care din 200 icircn 200 ms trimite tot ce s-a acumulat icircn

coada

Footnotes

2

Acest comportament a fost propus de David D Clark icircn iulie 1982 icircn RFC 813

Algoritmul Nagle

Acest algoritm3 icircncearcă să icircmbunătăţească performanţele exploatacircnd următoarea caracteristică

foarte des icircntacirclnită icircn dialogul dintre două staţii dacă se icircncearcă trimiterea unor date de

dimensiune mică icircnsă există icircncă date neconfirmate de partener atunci ele sunt buffer-ate şi

trimise icircntr-un segment mai mare cacircnd soseşte confirmarea aşteptată Icircn acest fel se poate evita

generarea datagramelor mici (tinygrame) icircn situaţia unei legături lente Icircn cazul unei legături

rapide confirmările vor veni repede şi icircntacircrzierea introdusă de algoritm va neglijabilă

Există icircnsă şi cazuri icircn care acest algoritm duce la deprecierea performanţelor mesajele scurte

generate de mişcările mouse-ului icircn cazul folosirii unui server X Window sau utilizarea tastelor

care trimit mai mult de un caracter (secvenţe escape) Pentru a rezolva aceste inconveninte API-

ul de utilizare a TCP-ului trebuie să ofere o modalitate de a dezactiva acest algoritm (icircn sistemele

bazate pe sockeţi există icircn acest scop opţiunea TCP_NODELAY)

Footnotes

algoritm3

Algoritmul aparţinacircnd lui John Nagle a fost propus icircn ianuarie 1984 icircn RFC 896

Fereastra glisantă

Algoritmul implementat de TCP pentru a implementa transferul sigur de date este cunoscut icircn

teorie sub numele de Go-Back-N Icircn acest algoritm se utilizează numere de secvenţă pentru a

distinge pachetele icircntre ele şi o coadă (dimensiunea maximă a cozii reprezintă fereastra) de

pachetele a căror confirmare se aşteaptă Pachetele se icircmpart icircn 4 categorii

1 pachete trimis şi pentru care s-a primit confirmare

2 pachete trimise şi pentru care se aşteaptă icircncă confirmarea

3 pachete care nu au fost trimise icircncă dar care nu depăşesc limitele ferestrei şi deci pot fi

trimise

4 pachete care icircncă nu au fost trimite şi care nici nu vor putea fi trimise decacirct după ce au

fost trimise toate pachetele din categoria 3 şi s-au primit o parte din confirmările la

pachetele din categoria 2

Dacă confirmările pentru pachetele din categoria 2 icircntacircrzie prea mult (un mecanism de timer-e

informează asupra acestui lucru) atunci ele vor fi retrimise Icircn versiunea iniţială TCP-ul nu

permitea decacirct confirmări pozitive ceea ce icircnseamnă că avansarea ferestrei se va icircmpotmoli la

segmentele neconfirmate Cum se poate evita aceasta situaţie vom discuta icircn detaliu icircn capitolele

următoare O soluţie foarte radicală o constituie introducerea de confirmări selective (acest lucru

este realizat de RFC 2018 din octombrie 1996) Această modifică face ca TCP-ul actual să fie un

hibrid de Go-Back-N şi Selective Repeat

Deoarece dimensiunea ferestrei este anunţată la fiecare segment un client lent poate ca pe măsură

ce trimite confirmările să informeze despre progresul icircnregistrat la livrarea datelor următorului

nivel (aplicaţie) Dacă datele vin prea repede pentru viteza cu care clientul procesează datele

fereastra fereastra se va dimiua şi chiar icircnchide (acest lucru se realizează anunţacircnd o fereastră de

dimensiune zero) Cum se realizează efectiv redeschiderea vom analiza icircntr-un capitol viitor

Slow start

Un transfer de date TCP poate să icircnceapă prin transmiterea de segmente pacircnă la umplerea

icircntregii ferestre după care fie se primesc confirmări care vor permite unor noi pachete să fie

trimise fie vor expira timer-ele de retransmisie şi se va icircncepe retrimiterea pachetelor de la

icircnceputul ferestrei Din păcate un astfel de comportament poate duce la pomparea icircn reţea a unui

număr de pachete prea mare pentru capacitatea disponibilă efectiv icircnrăutăţind congestia Pentru

a evita acest lucru s-a propus următoarea soluţie4 iniţial se trimite un segment după primirea

confirmării lui se trimit două segmente după sosirea confirmărilor pentru ele se trimit patru

segmente şi aşa mai departe La un moment dat fie vor icircncepe să se piardă segmente (un indiciu

că s-a atins capacitatea maximă a canalului) fie se va umple fereastra pe care o anunţă cel care

primeşte Trebuie să remarcam că datorită creşterii exponenţiale a numărului de segmente se va

atinge destul de repede una din cele două situaţii

Modalitatea efectivă de implementare a acestui algoritm are la bază utilizarea unei ferestre de

congestie (congestion window cwnd) care este iniţializată cu dimensiunea unui segment (cwnd

se calculează icircn octeţi) şi la fiecare pas este dublată fereastra efectivă din cadrul căreia se pot

trimite segmente este dată de minimul dintre ultima fereastra comunicată de partener şi cwnd

Footnotes

soluţie4

Soluţia aparţine lui V Jacobson şi a fost prezentată icircn 1988 la conferinţă ACM

SIGCOMM-88

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Deoarece TCP trebuie să funcţioneze icircn condiţii variate de latenţă modul icircn care se face

retransmiterea trebuie să fie cacirct mai flexibil (şi simplu icircn acelaşi timp pentru a introduce un

overhead cacirct mai mic) Timpul cacirct se aşteaptă venirea unei confirmări (retransmission timeout

RTO) este calculat prin cronometrarea timpului care icirci ia unui segment trimis să fie confirmat

Pentru o anumită conexiune se cronometrează cacircte un singur segment la un moment dat iar pe

baza RTT-ului măsurat se actualizează valoare RTO-ului

Icircn RFC 793 formula de calcul a RTO-ului este următoarea

unde este ultimul RTT măsurat este o estimare ponderată pentru RTT este un coeficient

de ponderare care icircn general are valoarea iar este un coeficient cu o valoare recomandată

de După cum se poate observa icircn valoarea lui este inclusă icircn mare măsură vechea valoarea

Icircn acest fel ajustarea RTT-ului se face treptat Din păcate acest mod de calcul nu funcţionează

bine la variaţii mari ale RTT-ului ducacircnd la creşterea numărului de retransmisii exact atunci

cacircnd fenomenul de congestie icircncepe să apară

Pentru a remedia aceste neajunsuri V Jacobsen a propus icircn 1988 o nouă metodă de calcul o

metodă care ţine seama seamă şi de modul icircn care variază diferenţa dintre RTT-uri Formulele

folosite sunt următoarele

unde este un estimare pentru media RTT-urilor este o estimare pentru abaterea RTT-urilor

faţă de medie (o aproximaţie suficientă pentru abaterea pătratică medie care icircnsă este mult mai

costisitor de calculat) este diferenţa dintre RTT-ul măsurat ( ) şi estimarea curentă ( )

Coeficientul cu care este actualizată estimarea curentă are valoarea de iar cel cu care este

actualizat estimarea abaterii este La stabilirea unei conexiuni valorile pentru şi sunt

alese astfel icircncacirct să rezulte un RTT de secunde şi un de 3 secunde (aceste recomandări

sunt făcute de RFC 1122)

Dacă pentru un anumit segment nu se primeşte confirmarea icircn intervalul indicat de el va fi

retrimis şi noul este dublat Valoarea maximă admisă pentru este de 240 secunde

Deoarece icircn cazul retrimiterilor nu se poate determina cu exactitate căruia din segmentele trimise

aparţine confirmarea actualizarea estimărilor este amacircnată pacircnă cacircnd se reuşeşte trimiterea

corectă (s-a primit confirmare) fără retransmitere(``din prima) a unui segment Acest artificiu

(deloc neimportant) care permite evitarea actualizarea eronată a estimărilor este cunoscut sub

numele de algoritmul lui Karn şi a fost propus icircn 1987 de P Karn şi C Partridge

Evitarea congestiei

Dacă cei doi parteneri care comunică prelucrează datele suficient de repede şi vor să transfere un

volum mare de date atunci limitarea de care se vor lovi este cea dată de viteza reţelei Din cauza

modului ``best-effort pe care IP-ul icircl oferă cacircnd canalul de comunicaţie este saturat o parte din

segmentele TCP se vor pierde Icircn mod poate paradoxal atacirct transmiţătorului cacirct şi receptorul se

pot afla icircn poziţia de a fi primii icircn detectarea pierderii unui segment Unul din indiciile de la

transmiţător care semnalează pierderea unui segment este (icircn mod evident) apariţia 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 icircn varianta iniţială nu

permite decacirct confirmări pozitive singurul lucru pe care receptorul icircl poate face este ca la fiecare

segment out-of-order primit să trimită o confirmare indicacircnd prin aceasta că la el continuă să

vină segmente icircnsă cel indicat de numărul de secvenţă de confirmare lipseşte Primirea acestor

confirmări multiple este al doilea mod icircn care transmiţătorul poate afla de apariţia congestiei

Algoritmul ce trebuie aplicat icircn momentul icircn care se detectează apariţia congestiei este cunoscut

sub numele de ``evitarea congestiei (congestion avoidence) Principiul care stă la baza lui este

ca la apariţia congestiei fie să se treacă la o incrementare liniară a dimensiunii ferestrei dacă

congestia a fost detectată ca urmare a primirii unor confirmări identice repetate fie să se reia

slow start-ul icircn cazul icircn care congestia s-a detectat prin expirarea unui timer de timeout

Implementarea acestui algoritm se bazează pe utilizarea unui nou contor (sstresh) care să indice

dimensiunea ferestrei de la care se trece de la incrementarea exponenţială la cea liniară

Algoritmul efectiv este următorul

1 la stabilirea unei noi conexiuni se pleacă cu sstresh iniţializat la valoare de 64K şi cwnd

la dimensiunea unui segment

2 trimiterea de segmente se face fără a depăşi minimul dintre fereastra publicată de partener

(pentru a nu depăşi capacitatea de procesesare a partenerului) şi cwnd-ul curent (pentru a

nu depăşi limita impusă de capacitatea reţelei)

3 la apariţia congestiei sstresh este setat la jumătatea valorii ferestrei curente (minimul

dintre fereastra anunţată de partener şi cwnd icircnsă cel puţin dimensiunea corespunzătoare

pentru două segmente) dacă congestia a fost detectată prin expirarea unui timer de

timeout atunci cwnd este iniţializat cu dimensiunea unui segment

4 la primirea unei confirmări incrementarea se face icircn două moduri icircn funcţie de relaţie icircn

care se află cwnd şi sstresh

1 dacă cwnd e mai mic sau egal cu sstresh se face incrementarea exponenţială

caracteristică slow start-ului (care de fapt nu e deloc slow icircn cazul de faţă)

2 dacă cwnd e mai mare ca sstresh atunci se face o incrementare cu dimensiunea

unui segment

Fast Retransmission Fast Recovery

După cum am văzut un receptor care primeşte segmente out-of-order va trimite transmiţătorului

confirmări duplicate Algoritmul denumit ``fast retransmission recomandă următoarele două

comportamenet

1 un receptor care detectează segmente out-of order trebuie să nu icircntacircrzie trimiterea de

confirmări (după cum am văzut icircn general confimările sunt icircntacircrziate micşora numărul de

pachete fără date care sunt transferate)

2 un transmiţător care care primeşte mai mult de trei confirmări duplicate trebuie să

retrimită segmentul indicat ca fiind neprimit de confirmările icircn cauză fără a aştepta

expirarea timer-ul de timeout

Algoritmul de ``fast recovery icircncearcă să optimizeze şi mai mult comportamentul

transmiţătorului care detectează un număr de trei sau mai multe confimări duplicate Mai exact el

recomandă trecerea la actualizarea liniară a ferestrei (congestion avoidance) Acest tip de

comportament se poate justifica prin următorul raţionament deoarece icircncă mai sunt transferate

date icircntre cei doi parteneri (şi acest lucru se icircntacircmplă sigur de vreme ce sosesc confirmări

duplicate icircn cazul acesta) icircnseamnă că transferul nu este afectat de o congestie severă şi prin

urmare trecerea la slow start nu e (icircncă) necesară (slow start-ul eliberează aproape complet

canalul deoarece cwnd este resetat la dimensiunea unui singur segment)

Cei doi algoritmi pot fi implementaţi icircn felul următor

1 cacircnd se detectează trei confirmări consecutive identice se setează sstresh la jumătate din

valoarea cwnd se retransmite segmentul care s-a pierdut şi se setează cwnd la valoarea

egală cu sstresh plus dimensiunea a trei segmente (acest lucru va face ca algoritmul de

incrementare a cwnd să treacă la incrementare liniară)

2 la fiecare confirmare duplicată care mai soseşte se incrementează cwnd se incrementează

cu dimensiunea unui segment

3 cacircnd icircncetează primirea de confirmări duplicate (segmentul retrimis a ajuns cu bine la

receptor şi s-a trimis o confirmare care acoperă segmentul care se pierduse iniţial) cwnd

este setat la valoarea sstresh

Sindromul ``Silly Window

Protocoalele bazate pe fereastră glisantă (cum este şi TCP-ul) pot să ajungă icircn situaţia deloc

fericită de trimite un număr mare de segmente mici icircn loc de segmente de dimensiune maximă

Acest tip de comportament este cunoscut sub numele de sindromul ``silly window

O modalitate prin care TCP-ul poate să cadă victimă acestui tip de comportament este

deschiderea de ferestre cu dimensiune foarte mică O altă situaţia nefericită este cea icircn care un

transmiţător este ``lacom şi trimite date indiferent de cacirct de mică este fereastra (după cum vom

vedea imediat uneori are sens şi un astfel de comportament) Algoritmul de evitare a acestor

neajunsuri este următorul

1 un receptor nu trebuie să anunţe deschideri de ferestre mici Mai exact nu se recomandă

anunţarea unei incrementări a ferestrei mai mică decacirct dimensiunea unui segment (MSS)

sau jumătate din buffer-ul aflat la dispoziţia receptorului oricare din ele e mai mică

2 un transmiţător va trimite date doar icircn următoarele cazuri

1 se poate trimite un segment icircntreg

2 se poate trimite jumătate din dimensiunea celei mai mari ferestre pe care

partenerul a publicat-o pacircnă acum

3 toate datele trimise pacircnă acum au fost confirmate sau algoritmul Nagle este

dezactivat şi se trimit toate datele care sunt icircn buffer-ul de trimitere

Cacircteva justificări cazul 2b tratează cazul icircn care partenerul anunţă ferestre mai mici decacirct

dimensiunea unui segment iar cazul 2c impune condiţiile respectării algoritmului Nagle după

cum se vede dacă algoritmul Nagle este activ şi s-au acumulat destul date mai exact cacirct

dimensiunea unui segment el va fi trimis chiar dacă există segmente neconfirmate Pentru

implementarea comportamentului impus de 2b un transmiţător trebuie să ţină evidenţa celei mai

mari ferestre pe care partenerul a anunţat-o Ţinacircnd seama că dimensiunea acestor buffer-e nu se

modifică acest mod de a icircncerca determinarea lor este suficient

O altă problemă legată tot de ferestre este cazul icircnchiderii acesteia Un mod icircn care s-ar putea

anunţa redeschiderea este trimiterea de către receptor a unei confirmări (duplicat) care să anunţe

redeschiderea la o anumită valoare a ferestrei Deoarece acest pachet nu trebuie confirmat icircn mod

special şi s-ar putea să se piardă se poate ajunge icircn situaţia icircn care receptorul a anunţat

redeschiderea ferestrei segmentul s-a pierdut iar transmiţătorul icircncă mai icircl mai aşteaptă pentru a

putea continua transferul Rezolvarea la această problemă s-a făcut prin impunerea unui alt

comportament

1 transmiţătorul va trimite segmente cu dimensiunea datelor de un octet prin care sondează

deschiderea ferestrei intervalul la care se sondează redeschiderea ferestrei se dublează

(exponenţial backoff) icircn RFC 793 dimensiunea maximă recomandată este de 2 minute

icircnsă icircn RFC 1122 se specifică că maximul este acelaşi cu cel din cazul retransmisiei (240

secunde)

2 receptorul trebuie să refuze aceste pachete răspunzacircnd cu segmente de confirmare care

indică neprimirea octetului respectiv

Observaţie timer-ul special necesar pentru implementare la transmiţător a comportamentului de mai sus este cunoscut sub numele de ``TCP Persistent Timer Numele este justificat de faptul că sondarea deschiderii se va face pacircnă cacircnd fie fereastra se deschide fie conexiunea se icircntrerupe TCP Keepalive Timer

Un lucru interesant despre TCP este faptul că dacă nivelele superioare nu comunică nimic icircntre

ele pentru o perioadă lungă 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 icircn care au trecut cu succes de faza stabilirii legăturii Dacă nivelurile

inferioare (reţeaIP fizic) devin temporar indisponibile cacirct tip cei doi nu vor să comunice atunci

acest lucru nu va perturba icircn nici un fel activitatea şi acest lucru este acceptabil Problemele

icircncep să apară icircn momentul icircn care cei doi doresc să comunice şi nivelele inferioare nu mai

permit acest lucru Evident că cel care va dori să comunice ceva va detecta icircntreruperea legăturii

şi va icircnchide conexiunea Ce se icircntacircmplă icircnsă dacă celălalt capăt nu are nimic de comunicat (de

exemplu este un server care oferă anumite servicii) Pentru el legătura va fi icircn continuare activă

şi icircn general anumite resurse vor fi rezervate pentru aceasta Rezolvarea acestei situaţii este dată

de introducerea unei mecanism de sondare a stării legăturii pe baza unui timer (TCP Keepalive

Timer) care se declanşează din două icircn două ore La fiecare expirare a timer-ului se trimite un

segment fără date care confirmă datele primite pacircnă atunci Răspunsul care trebuie primit este tot

un segment fără date care confirmă datele primite de partener (practic o re-publicare a stării celor

doi parteneri) Dacă răspunsul nu este primit timp de 75 secunde atunci segmentul va fi retrimis

Dacă după 10 astfel de icircncercări tot nu s-a primit nici un răspuns atunci conexiunea se va

considera terminată şi se va anunţa nivelul superior asupra acestui lucru

Observaţii

dacă o staţie primeşte segmente de keepalive despre conexiuni care nu mai sunt active

(de exemplu a fost resetat) atunci va răspunde cu segmente de reset (acesta e un procedeu

standard)

RFC 1122 specifică că facilitatea de keepalive trebuie activată icircn mod explicit

3 Studii de caz

Subsections

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

1 Fragmentarea pachetelor UDP

Deoarece UDP-ul este un serviciu fără conexiune toate datele pe care le primeşte de la nivelul

superior sunt icircncapsulate icircntr-o singură datagramă UDP care apoi va forma un pachet IP Dacă

pachetul IP astfel obţinut este prea mare atunci mecanismele IP de fragmentare icircl vor sparge icircn

bucăţi Exemplul următor icircncearcă să studieze exact acest fenomen

Pe maşina athos rulează un server de UDP pe portul 50007 Pe o altă maşină frodo aflată icircn

reţeaua locală este rulat un client care poate fi configurat să trimită un pachet UDP de o anumită

lungime Pentru a putea observa ce se icircntacircmplă pe athos este rulat tcpdump

Deoarece MTU-ul pentru o reţea Ethernet este icircn general 1500 şi antetul IP plus cel UDP ocupă

20 + 8 = 28 octeţi o datagramă UDP de dimensiune 1472 ar trebui sa fie trimisă nefragmentată

Pentru siguranţă folosind clientul de pe athos s-a trimis mai icircntacirci o datagramă UDP cu 1471

octeţi de date şi apoi icircncă una cu 1472 Pentru ambele tcpdump a indicat trimiterea lor fără

fragmentare

182556721144 frodonoi33274 gt athosnoi50007 udp 1471 (DF) (ttl 64 id

51481 len 1499)

182559846764 frodonoi33274 gt athosnoi50007 udp 1472 (DF) (ttl 64 id

51793 len 1500)

La o dimensiune de 1473 ar trebui ca trimiterea să genereze două pachete IP unul care să

conţină primii antetul UDP plus primii 1472 octeţi de date şi icircncă un pachet IP care conţine un

singur octet Iată ce indică tcpdump-ul

182605705813 frodonoi gt athosnoi udp (frag 3627411480) (ttl 64 len

21)

182605706116 frodonoi33274 gt athosnoi50007 udp 1473 (frag

3627414800+) (ttl 64 len 1500)

Intr-adevăr au fost generate două pachete IP

primul conţine doar un singur octet de date şi reprezintă ultimul fragment (bitul de more

fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest

lucru) care a fost spartă icircn bucăţi deplasamentul octetului primit in datagrama originală

este 1480

al doilea pachet este primul fragment din datagrama UDP şi conţine antetul UDP (din

cauza asta datele efective ocupă doar 1480 octeţi) deplasamentul este 0 şi bitul de more

fragments este setat (acest lucru este indicat de semnul ``+ de după deplasament)

După cum se poate observa ambele pachete poartă acelaşi număr de identificare (36274) Acest

lucru icircmpreună cu informaţiile date de flag-ul more fragments permite reconstrucţia la

destinaţie a datagramei UDP originale O problemă a acestui mod de fragmentare e că icircn cazul

pierderii unui fragment icircntreaga datagramă va fi compromisă şi va trebui retrimisă icircn icircntregime

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 2: udp tcp

4 Controlul fluxului

o 3 Studii de caz

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

Bibliografie

About this document

7 Protocoale TCPIP la nivelul transport

Subsections

1 UDP

o 1 Caracteristici UDP

o 2 Formatul pachetelor UDP

2 TCP

o 1 Caracteristici TCP

o 2 Formatul pachetelor TCP

o 3 Iniţierea şi terminarea unei conexiuni TCP

Protocolul de iniţiere

1 Deschiderea simultană

Protocolul de terminare

2 Terminarea simultană

3 Resetarea conexiunii

Diagrama de stări

o 4 Controlul fluxului

Icircntacircrzierea confirmărilor

Algoritmul Nagle

Fereastra glisantă

Slow start

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Evitarea congestiei

Fast Retransmission Fast Recovery

Sindromul ``Silly Window

TCP Keepalive Timer

3 Studii de caz

o 1 Fragmentarea pachetelor UDP

o 2 Stabilirea şi eliberarea unei conexiuni TCP

o 3 Transferul de date TCP

1 UDP

Subsections

1 Caracteristici UDP

2 Formatul pachetelor UDP

1 Caracteristici UDP

UDP (User Datagram Protocol) este un protocol de nivel transport construit special pentru a oferi

un serviciu de comunicare cacirct mai simplu peste IP Specificaţiile protocolului au fost publicate icircn

1980 icircn RFC-ul cu numărul 7681

Cacircteva caracteristici ale UDP-ului sunt

este un serviciu de tip datagramă cererile de trimitere de date primite de la nivelul

superior sunt tratate independent

comunicarea are loc fără stabilirea unei legături (conection-less) nu există mecanisme de

stabilire şi terminare a unei conexiuni deoarece toate datele sunt trimise icircn cadrul unui

singur pachet IP care eventual va fi supus fragmentării

nu se garantează ajungerea ala destinaţie a datelor (best effort) ajungerea la destinaţie nu

este anunţată sursei

datele transportate sunt protejate de o sumă de control (introdusă ca opţională iniţial ea

este trecută ca necesară(must) icircn RFC 1122 care stabileşte modul de comportare al

clienţilor icircn Internet)

overhead-ul introdus este minim doar 8 octeţi

Cacircteva utilizări tipice ale UDP-ului

servicii de rezolvare a numelor (DNS) deoarece icircntrebările şi răspunsurile 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 fişiere (NFS) deoarece acest tip de aplicaţii sunt icircn general rulate icircn reţele

locale cu performanţe ridicate care nu necesită mecanismele TCP

managementul reţelei (SNMP)

protocoale de rutare (RIP)

Footnotes

7681

RFC 768 are nici mai mult nici mai puţin decacirct 3 pagini nu conţine cuprins dar are o listă

de 5 referinţe bibliografice

2 Formatul pachetelor UDP

Datagramele UDP sunt formate dintr-un antet (figura 71) urmat de datele care se doresc

transmise (dacă există)

Figura 71 Structura unei datagrame UDP

Antetul cuprinde

port sursă - 16 biţi

Icircmpreună cu adresa IP a sursei acest număr identifică icircn mod unic locul de unde a fost

trimis datagrama UDP

port destinaţie - 16 biţi

Icircmpreună cu adresa IP a destinaţiei acest număr identifică icircn mod unic destinaţia dorită

pentru datagrama UDP

lungimea pachetului UDP - 16 biţi

Lungimea minimă măsoară datagrama UDP cu tot cu antent şi prin urmare are o valoare

minimă de 8 octeţi

sumă de control - 16 biţi

Suma de control acoperă icircntreg pachetul UDP cacirct şi un pseudo antet de 12 octeţi format

din

adresa IP a sursei - 32 biţi

o adresa IP a destinaţiei - 32 biţi

8 biţi de zero pentru aliniere

numărul protocolului UDP (17) reprezentat pe 8 biţi

lungimea pachetului UDP - 16 biţi

Deoarece suma de control necesită icircn calculul ei un număr multiplu de 16 octeţi la

sfacircrşitul datelor se adaugă un număr potrivit de octeţi de zero Dacă suma este 0 atunci ea

va fi stocată ca 65535 (toţi biţii pe 1) Un 0 icircn cacircmpul de sumei de control indică faptul

că suma de control nu a fost calculată Observaţie chiar dacă un client are inhibat (icircn

mod explicit) calcului sumei de control el este obligat să verifice suma pachetelor care

sosesc şi au suma calculată

2 TCP

Subsections

1 Caracteristici TCP

2 Formatul pachetelor TCP

3 Iniţierea şi terminarea unei conexiuni TCP

o Protocolul de iniţiere

1 Deschiderea simultană

o Protocolul de terminare

2 Terminarea simultană

3 Resetarea conexiunii

o Diagrama de stări

4 Controlul fluxului

o Icircntacircrzierea confirmărilor

o Algoritmul Nagle

o Fereastra glisantă

o Slow start

o Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

o Evitarea congestiei

o Fast Retransmission Fast Recovery

o Sindromul ``Silly Window

o TCP Keepalive Timer

1 Caracteristici TCP

Deoarece protocolul IP este de tip datagramă utilizarea lui direct icircn aplicaţii care in general au

nevoie de conexiuni sigure este mult prea anevoioasă Din aceste motive peste IP a fost construit

un alt protocol TCP (transimission control protocol) care corectează aceste probleme Prima

definire se găseşte icircn RFC-ul cu numărul 793 şi datează din septembrie 1981 Din cauza deselor

congestii apărute icircn 1986 algoritmul care stă la baza TCP-ului este reanalizat şi icircn octombrie

1989 icircn RFC-ul cu numărul 1122 este publicată o nouă specificare mult mai eficientă şi

neambiguă a TCP-ului Noi probleme legate de viteze mari sunt tratate icircn RFC-ul 1323 iar icircn

2018 TCP-ul este extins pentru a permite confirmările selective (selective acknowledge) Seria

de RFC-urie fundamentale este icircncheiată de apariţia icircn 1989 a RFC-ului cu numărul 2581 Icircn el

se specifică foarte strict comportamentul care este permis pentru o implementare de TCP

Alături de protocolul UDP TCP se situează pe nivelul transport icircn ierarhia de protocoale deci

icircntre nivelul aplicaţie şi nivelul reţea Dar cu toate că se bazează pe acelaşi protocol (IP) ca şi

UDP TCP furnizează către nivelul aplicaţie cu totul alt tip de servicii servicii orientate-

conexiune sigure de tip flux de octeţi

Termenul de orientat-conexiune presupune că icircntre cele două aplicaţii care comunică utilizacircnd

TCP trebuie să se stabilească o conexiune TCP icircnainte ca transferul de date să aibă loc Această

conexiune nu este efectiv una fizică ci virtuală asemănător cum se icircntacircmplă icircn sistemul de

telefonie clasică cineva formează un număr şi abia icircn momentul icircn care cealaltă persoană

răspunde se poate icircncepe conversaţia Fiind o conexiune host-la-host nu există noţiunile de

broadcast sau multicast

Transferul sigur de date este asigurat icircn următorul mod

Datele sunt icircmpărţite icircn bucăţi a căror dimensiune optimă e determinată de TCP spre

deosebire de UDP care trimite datagrame UDP corespunzătoare cu dimensiunea datelor

primite de la nivelul aplicaţie Unitatea de date trimisă de TCP către nivelul reţea poartă

numele de segment

Cacircnd TCP trimite un segment porneşte un timer şi dacă nu se primeşte confirmarea

segmentului respectiv icircntr-un anumit timp icircl retransmite

Icircn momentul icircn care se primeşte un segment TCP trimite o confirmare (din motive de

eficienţă aceasta poate fi amacircnată un anumit interval de timp)

Icircn headerul TCP este menţinută o sumă de control pentru detectarea modificărilor icircn date

Dacă se recepţionează un segment corupt TCP icircl ignoră urmacircnd să fie retransmis datorită

neprimirii confirmării

Deoarece segmentele TCP sunt transmise mai departe icircncapsulate icircn datagrame IP iar

acestea pot ajunge icircn orice ordine segmentele TCP pot ajunge icircn altă ordine decacirct cea icircn

care au fost trimise De aceea la destinaţie TCP-ul trebuie să se folosească de numere de

secvenţă pentru a reordona eventual segmentele icircnainte de a le livra către nivelul

aplicaţie De asemenea TCP trebuie să asigure ignorarea duplicatelor

TCP asigură controlul fluxului icircn condiţiile icircn care viteza de trimitere a datelor de la sursă

poate fi mult prea mare decacirct capacitatea de prelucrare de la destinaţie

Serviciul oferit de TCP este de tip flux de octeţi deoarece oferă garanţii că fluxul de date trimis

de sursă va fi livrat fără modificări la destinaţie Comparativ UDP-ul produce pentru fiecare

transfer cerut de nivelul aplicaţie un pachet IP (care ulterior poate fi supus fragmentării) care

dacă ajunge la destinaţie corect va fi livrat direct nivelului aplicaţie fără a garanta icircn vreun fel

ordinea

2 Formatul pachetelor TCP

Pachetele de date transmise de TCP segmentele sunt formate dintr-un antet (figura 72) de 20

octeţi urmat de datele primite de la nivelul aplicaţie Antetul poate uneori conţine şi o serie de

opţiuni caz icircn care poate ajunge la 60 octeţi

Figura 72 Structura unui segment TCP

Antetul unui segment TCP cuprinde

port sursă - 16 biţi pentru specificarea portului aplicaţiei transmiţătoare

port destinaţie - 16 biţi pentru specificarea portului aplicaţiei ce recepţionează segmentul

TCP

Aceste două porturi icircmpreună cu adresele ale sursei şi destinaţiei conţinute icircn antet-ul IP

identifică icircn mod unic conexiunea Pentru o pereche formată dintr-o adresă IP şi un port

se foloseşte adesea denumirea de socket (denumire introdusă icircn specificaţiile iniţiale ale

protocolului TCP icircn RFC 793)

număr de secvenţă - 32 biţi

Pentru a asigura un serviciu de tip flux de octeţi TCP numerotează fiecare octet de date

utilizacircnd un număr de secvenţă Numărul de secvenţă din cadrul antetului TCP specifică

destinaţiei care este primul octet din fluxul trimis La iniţierea unei conexiuni se setează

flag-ul SYN şi se alege aleator un număr de secvenţă de icircnceput utilizacircnd un generator de

numere de secvenţă ISN (Initial sequence number) Numărul de secvenţă al primului

octet de date va fi numărul generat ISN plus 1 deoarece pachetul de iniţiere (cu SYN

setat) consumă şi el un număr de secvenţă Se va vedea mai departe că şi flag-ul de

terminare a conexiunii FIN consumă şi el un număr de secvenţă

confirmare - 32 biţi

Reprezintă numărul de secvenţă al octetului de date pe care transmiţătorul confirmării se

aşteaptă să-l primească Astfel dacă s-a recepţionat octetul cu numărul de secvenţă x (icircn

numerotaţia sursei) pachetul de confirmare va avea flag-ul ACK setat şi va conţine

numărul de confirmare x + 1 Trimiterea unui ACK nu consumă un număr de secvenţă

deoarece atacirct acest cacircmp cacirct şi flag-ul ACK fac parte din antet şi după stabilirea

conexiunii ambele cacircmpuri devin active Acest mecanism nu permite confirmări selective

pentru că numărul de secvenţă specifică pacircnă unde s-au recepţionat date De exemplu

dacă la destinaţie au ajuns octeţii 1-1024 şi următorul segment primit conţine octeţii

2049-3072 nu se poate trimite confirmare pentru cel de-al doilea segment deci

confirmarea va cuprinde numărul de secvenţă 1025

lungimea antetului - 4 biţi

Specifică dimensiunea antetului ca număr de cuvinte de 32 de biţi (4 octeţi) Antetul

poate avea icircntre 20 şi 60 de octeţi deci valoarea acestui cacircmp va fi icircntre 5 (5 x 4 = 20

octeţi) şi 15 (15 x 4 = 60)

6 biţi rezervaţi pentru utilizări viitoare

6 biţi de control reprezentacircnd următoarele flag-uri ce pot fi setate simultan

o URG - cacircmpul urgent pointer este valid

o ACK - cacircmpul de confirmare este valid

o PSH - destinaţia trebuie să trimită datele către nivelul aplicaţie cacirct mai devreme

o RST - se doreşte resetarea conexiunii

o SYN - iniţierea conexiunii

o FIN - icircnchiderea conexiunii

dimensiunea ferestrei - 16 biţi

Reprezintă numărul de octeţi (icircncepacircnd cu numărul de secvenţă conţinut icircn cacircmpul de

confirmare) pe care destinaţia e dispusă să-l primească Este limitat la 65535 octeţi dar

cu toate că pare o limită destul de mare există situaţii cacircnd se doresc valori mult mai

mari Icircn acest scop se folosesc nişte opţiuni speciale descrise ceva mai tacircrziu care permit

scalarea ferestrei

suma de control - 16 biţi

Această sumă de control acoperă icircntregul segment TCP (atacirct datele cacirct şi antetul TCP) şi

spre deosebire de UDP este obligatoriu să fie completat de transmiţător şi verificat de

receptor Dar ca şi icircn cazul UDP-ului la calculul sumei de control se ia in considerare şi

o zona specială de 12 octeţi ce cuprinde pentru re-verificare cacircmpuri din antetul IP

(adresa IP a sursei şi a destinaţiei)[aici tre sa vina o referire la poza cu pseudo-antetu]

După adăugarea acestui pseudo-antet datele se icircmpart icircn cuvinte de 16 biţi icircn vederea

calculării sumei de control adăugacircndu-se eventual şi un octet de aliniere

urgent pointer - 16 biţi

Este utilizat pentru specificarea deplasamentului ultimului octet de date trimis icircn regim

urgent Astfel ultimul octet din secvenţa urgentă se obţine adunacircnd acest cacircmp la

numărul de secvenţă Ce icircnseamnă acest mod urgent de transmitere există situaţii icircn care

aplicaţiile vor să trimită date `neordonate` Să presupunem că aplicaţia a trimis către

nivelul transport o cantitate mare de date dar la un moment dat observă ceva icircn neregulă

şi doreşte să anuleze operaţia Dacă trimite o comandă de anulare aceasta va fi adăugată

la sfacircrşitul şirului de octeţi deci nu se va putea icircmpiedica ajungerea acestora la nivelul

aplicaţie de la receptor Activacircnd modul urgent datele urgente (comanda de anulare) vor

fi plasate la icircnceputul pachetului Aplicaţiile mai cunoscute care folosesc acest mod sunt

Telnet Rlogin şi FTP

opţiuni - pacircnă la 40 de octeţi (figura 73)

Cele mai utilizate opţiuni sunt

o Sfacircrşit de opţiuni (end of option) - 1 octet

Este utilizat pentru alinierea datelor conţinute icircn cacircmpul de opţiuni Nu poate fi

utilizat decacirct o singură dată marcacircndu-se astfel sfacircrşitul opţiunilor şi icircnceperea

datelor efective Dacă pentru alinierea la un cuvacircnt de 32 de biţi e nevoie de mai

mult de 1 byte se va utiliza opţiunea no operation Orice apare după această

opţiune pacircnă la icircnceputul cuvacircntului următor de 32 de biţi e ignorat

o no operation - 1 octet

Utilizat pentru alinierea la cuvinte de 32 de biţi

o Dimensiunea maximă a segmentului (Maximum Segment Size (MSS)) - 16 biţi

Icircn ciuda denumirii defineşte lungimea maximă a datelor nu dimensiunea

icircntregului segment Poate lua valori icircntre 0 şi 65535 valoarea implicită fiind 536

Această opţiune e valabilă doar icircn pachetele de iniţiere a conexiunii (cele cu flag-

ul SYN setat) fiecare parte făcacircnd cunoscută dimensiunea maximă a datelor

dispusă să le primească icircntr-un pachet Icircn principiu cu cacirct această valoarea e mai

mare e mai bine (deoarece se recuperează din spaţiul ocupat de antetele TCP şi

IP) pacircnă cacircnd apare fragmentarea Valoarea maximă la care se poate seta este

MTU (Maximum Transfer Unit) minus dimensiunea antetului IP şi TCP (1460

octeţi icircn cazul Ethernet)

o Factor de scalare a ferestrei (Window scale factor) - 1 octet

Pentru situaţiile icircn care se doreşte utilizarea unei ferestre mai mare de 65535 bytes

se poate utiliza acest cacircmp pentru mărirea dimensiunii ferestrei Noua dimensiune

va fi Chiar dacă

factorul de scalare poate fi maxim 255 icircn cazul TCPIP el nu poate depăşi

valoarea 16 deoarece dimensiunea maximă a ferestrei nu poate fi mai mare decacirct

valoarea celui mai mare număr de secvenţă ( )

Acest factor se poate seta doar la iniţierea conexiunii Icircn timpul transferului de

date se poate modifica dimensiunea ferestrei dar factorul de scalare rămacircne

acelaşi Dacă cel care a iniţiat conexiunea a trimis icircn segmentul de iniţiere şi acest

factor dar icircn pachetul cu ACK destinatarul nu şi-a trimis şi el factorul atunci se la

considera 0 icircn ambele direcţii Invers dacă cel care solicită deschiderea

conexiunii nu setează factorul destinaţia nu va putea seta factorul de scalare

o Timestamp - 10 octeţi

Utilizat pentru reţinerea timpului icircn vederea calculării RTT (Round Trip Time)

Cacircmpul timestamp e completat de sursă icircn momentul trimiterii segmentului La

destinaţie valoarea este reţinută şi copiată icircn cacircmpul timestamp echo reply al

pachetului cu confirmarea RTT-ul este calculat de sursă făcacircnd diferenţa dintre

timpul curent şi această valoare

Figura Opţiuni TCP

3 Iniţierea şi terminarea unei conexiuni TCP

TCP este un protocol orientat conexiune deci presupune stabilirea unei căi virtuale icircntre sursă şi

destinaţie

Subsections

Protocolul de iniţiere

o 1 Deschiderea simultană

Protocolul de terminare

o 2 Terminarea simultană

o 3 Resetarea conexiunii

Diagrama de stări

Protocolul de iniţiere

Modul de transmisie icircn cazul protocolului TCP este full-duplex deci sunt transmise date

simultan icircn ambele direcţii Aceasta presupune că cel care iniţiază conexiunea trebuie să

primească aprobarea celuilalt capăt icircnainte de icircnceperea transferului de date sursa icircşi anunţă

intenţia de a iniţia o conexiune destinaţia trimite un pachet cu confirmarea cererii şi un pachet de

iniţiere a conexiunii de la el la sursă iar apoi sursa confirmă cererea primită de la destinaţie Paşii

2 şi 3 pot fi realizaţi prin trimiterea unui singur pachet de aceea protocolul de iniţiere este

cunoscut sub numele de three-way handshake

Icircn cadrul protocolului de iniţiere există 2 tipuri de cereri de iniţiere cerere activă (active open)

iniţiată de clientul ce doreşte să stabilească conexiunea cu serverul şi cerere pasivă (passive

open) din partea serverului

Cei 3 paşi sunt

1 Clientul trimite un segment cu flag-ul SYN setat şi care conţine portul sursă portul de la

destinaţie şi numărul de secvenţă generat iniţial (ISN) de la care se vor numerota octeţii

de la client către server Opţional se pot stabili parametrii conexiunii prin setarea lungimii

maxime a segmentelor (MSS) dispus să le primească de la server factorului de scalare a

ferestrei Acest prim segment nu conţine nici un parametru de confirmare şi de asemenea

nu are rost să conţine să seteze dimensiunea ferestrei

2 Al doilea segment e trimis de server şi are un rol dublu confirmă segmentul primit de la

client prin setarea flag-ului ACK şi completează numărul de secvenţă cu numărul de

secvenţă primit plus 1 şi al doilea rol iniţializează conexiunea de la el către client prin

setarea flag-ului SYN şi generarea unui număr de secvenţă iniţial ce va fi folosit icircn

numerotarea octeţilor de la server spre client Pe lacircngă aceasta trebuie să conţină

dimensiunea ferestrei şi opţional poate seta factorul de scalare şi dimensiunea maximă a

segmentului acceptat

3 Clientul trimite un segment cu confirmarea cererii din partea serverului (ACK setat +

completează numărul confirmat cu numărul de secvenţa primit + 1) Ca şi icircn cazul

pasului 2 trebuie să seteze dimensiunea ferestrei Acest pachet poate conţine date

Subsections

1 Deschiderea simultană

1 Deschiderea simultană

Se poate icircntacircmpla ca uneori cele două capete care vor să comunice să icircncerce să stabilească

conexiunea simultan Icircn acest caz după ce fiecare a trimis segmentul de iniţiere (iniţiere activă)

ambele vor trimite un segment cu SYN + ACK şi se va stabili o singură conexiune nu două

Protocolul de terminare

Oricare dintre cele două părţi poate solicita icircnchiderea conexiunii dar conexiunea fiind full-

duplex transferul de date icircn celălalt sens poate continua (această situaţie e denumită half-close)

O icircnchidere completă a unei conexiuni TCP presupune următorii paşi

1 Clientul trimite un segment cu flag-ul FIN activat solicitacircnd icircnchiderea conexiunii

2 Serverul trimite un segment ACK confirmacircnd primirea cererea Numărul de confirmare

se completează normal ca numărul de secvenţă primit + 1

3 Serverul continuă să trimită date către client şi cacircnd doreşte să icircnchidă şi el conexiunea

trimite un segment cu FIN activat

4 Clientul trimite un pachet ACK confirmacircnd icircnchiderea conexiunii

Cel care iniţiază primul procedura de icircnchidere (trimite primul FIN) realizează o icircnchidere activă

(active close) iar celălalt capăt o icircnchidere pasivă (passive close) Icircn mod normal cel care

realizează iniţierea activă va fi primul ce va trimite FIN dar oricare dintre cei doi poate icircnchide

activ conexiunea

Subsections

2 Terminarea simultană

3 Resetarea conexiunii

2 Terminarea simultană

Icircn mod similar cu deschiderea simultană există posibilitatea ca ambele capete ale conexiunii TCP

să iniţieze simultan procedura de icircnchidere a conexiunii Icircn acest caz ambele părţi vor trimite

FIN şi vor aştepta primirea unui ACK Icircn continuare fiecare va primi cererea de terminare şi va

trimite ACK Se observă că numărul de segmente transferate pentru realizarea icircnchiderii

conexiunii (4 segmente) este acelaşi ca la terminarea normală

3 Resetarea conexiunii

Există situaţii icircn care TCP doreşte resetarea conexiunii De exemplu dacă se solicită iniţierea

unei conexiuni la un port inexistent Icircn acest caz cealaltă parte va trimite un segment cu bitul

RST setat pentru a anula solicitarea O altă situaţie este atunci cacircnd se constată că celalalt capăt

al conexiunii nu răspunde un anumit timp (timeout)

Diagrama de stări

Toate evenimentele ce au loc icircn timpul stabilirii conexiunii transferului şi icircnchiderii conexiunii

pot fi rezumate printr-un automat finit cunoscut sub numele de diagrama de stări După cum

chiar numele sugerează este o maşină cu un număr limitat de stări O stare este păstrată pacircnă icircn

momentul apariţiei unui eveniment moment icircn care se poate trece icircn altă stare şisau efectua o

acţiune

Aceste stări posibile sunt (denumirile sunt asemănătoare cu cele utilizate de netstat) cele din

tabelul 71

Tabela Stările diagramei de stări TCP

Stare Descriere

CLOSED Nu există conexiune

LISTEN Serverul aşteaptă cereri de la clienţi

SYN_SENT Cerere de iniţiere (activă) a conexiunii Se

aşteaptă confirmarea

SYN_RCVD S-a primit o cerere de iniţiere conexiune

ESTABLISHED S-a stabilit conexiunea

FIN_WAIT_1 Aplicaţia a solicitat icircnchiderea conexiunii

FIN_WAIT_2 Serverul a acceptat icircnchiderea conexiunii

CLOSING Ambele părţi solicită simultan icircnchiderea

conexiunii

TIME_WAIT Conexiune icircnchisă dar se aşteaptă ca

pachetele retransmise să dispară

CLOSE_WAIT Serverul aşteaptă icircnchiderea dinspre partea

aplicaţiei

LAST_ACK Serverul a icircnchis conexiunea Aşteaptă

ultima confirmare

Icircn diagrama ilustrată icircn figura 74 putem observa 3 tipuri de tranziţii icircntre cele 11 stări tranziţii

ce corespund unei funcţionări normale pentru client (linii normale continue) pentru server (linii

normale icircntrerupte) şi tranziţii pentru situaţii nestandard (linii subţiri continue)

O comportarea normală pentru client presupune parcurgerea următoarelor stări CLOSED

SYN_SEND ESTABLISHED FIN_WAY_1 FIN_WAY_2 TIME_WAIT

Iniţial clientul TCP se află icircn starea CLOSED

Aşteptacircnd icircn starea CLOSED clientul poate primi de la aplicaţie o cerere de iniţiere

activă a unei conexiuni Trimite un segment SYN şi trece icircn starea SYN_SENT

Icircn starea SYN_SENT clientul aşteaptă de la server un segment ACK+SYN după care

trimite un ACK şi trece icircn starea ESTABLISHED Din acest moment poate icircncepe

transferul efectiv de date Clientul va rămacircne icircn această stare cacirct timp are de trimisprimit

date

Aflat icircn această stare clientul TCP poate primi din partea aplicaţiei o cerere de icircnchidere a

conexiunii Icircn acest caz va trimit un segment FIN şi trece icircn starea FIN_WAIT_1

Icircn această stare clientul aşteaptă ACK din partea serverului După ce-l primeşte

conexiunea icircntr-un sens se va icircnchide şi clientul trece icircn starea FIN_WAIT_2

Starea FIN_WAIT_2 durează pacircnă cacircnd primeşte cererea de icircnchidere a conexiunii FIN

din partea serverului Trimite ACK şi va trece icircn starea TIME_WAIT

Icircn această stare se va porni un timer cu valoarea setată la dublul timpului de viaţă estimat

pentru un segment de lungime maximă MSL (Maximum Segment Lifetime) Acest timer

permite retransmiterea ACK-ului icircn cazul icircn care acesta se pierde (celălalt capăt va da

timeout şi va retransmite segmentul FIN) Icircn tot acest time cei doi sockeţi (de la client şi

server) nu vor putea fi reutilizaţi Totodată pachetele icircntacircrziate care sosesc icircn această

perioadă sunt ignorate După expirarea acestui timer clientul revine icircn starea iniţială

CLOSED

Din punctul de vedere al unui server o comportare standard parcurge următoarele stări

CLOSED LISTEN SYN_RCVD ESTABLISHED CLOSE_WAIT şi LAST_ACK

Iniţial serverul TCP se află icircn starea CLOSED

Icircn această stare poate primi de la aplicaţia server o cerere de iniţiere activă şi trece icircn

starea LISTEN

Aflat icircn starea LISTEN serverului TCP poate recepţiona un segment SYN de la un client

TCP Icircn acest caz va trimite ACK+SYN şi va trece icircn starea SYN_RCVD

Icircn această stare serverul aşteaptă primirea confirmării de la client moment icircn care

conexiunea e stabilită icircn ambele sensuri şi se poate icircncepe transferul de date (starea

ESTABLISHED)

Clientul TCP poate solicita icircnchiderea conexiunii trimiţacircnd un segment FIN către server

Icircn acest caz serverul TCP trimite confirmarea şi trece icircn starea CLOSE_WAIT

Icircn această stare serverul aşteaptă să primească din partea programului server icircnchiderea

conexiunii moment icircn care va trimite către client un segment FIN şi trece icircn starea

LAST_ACK

Serverul aşteaptă primirea ultimei confirmări de la client după care revine icircn starea

CLOSED

Atacirct serverul cacirct şi clientul TCP se pot afla icircn oricare din cele 11 stări ale diagramei

Figura Diagrama de stări pentru TCP

4 Controlul fluxului

Dacă icircncă de la icircnceput s-a reuşit stabilirea formatului unui pachet TCP şi a modulului icircn care

trebuie să se facă icircnchiderea şi deschiderea unei conexiuni nu acelaşi lucru se poate spune şi

despre modul icircn care ar trebui să se realizeze controlul fluxului Ţinacircnd seama icircnsă că din 1989

(de cacircnd datează RFC-ul 2581 cel despre care am menţionat că specifică icircn mod clar modul icircn

care trebuie să se comporte o implementare de TCP) TCP-ul a rămas neschimbat putem să icircl

considerăm un rezultat important al domeniului reţelor de calculatoare

Icircn cele ce urmează vom icircnţelege prin controlul fluxului totalitatea algoritmilor care permit

atingerea unei viteze de transfer punct-la-punct cacirct mai mare pentru toate conexiunile existente

Icircn principal aceşti algoritmi stabilesc modul icircn care segmentele şi confirmările trebuie trimise şi

ce acţiuni trebuie executate icircn situaţiile icircn care răspunsurile aşteptate de la celălalt capăt icircntacircrzie

să vină

Subsections

Icircntacircrzierea confirmărilor

Algoritmul Nagle

Fereastra glisantă

Slow start

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Evitarea congestiei

Fast Retransmission Fast Recovery

Sindromul ``Silly Window

TCP Keepalive Timer

Icircntacircrzierea confirmărilor

O modalitate simplă de generare a confirmărilor este de a trimite cacircte una pentru fiecare segment

primit Această politică prezintă avantajul de a face comunicaţia self-clocking icircnsă este

ineficientă dacă segmentele care nu conţin decacirct confirmări sunt urmate la scurtă distanţă (cacircteva

zeci de milisecunde) de segmente ce conţin date efective Pentru a evita această situaţie se

procedează2 la icircntacircrzierea (200ms este o valoare uzuală icircn RFC 1122 se specifică o valoare

maximă de 500ms) a segmentelor care conţin doar confirmări Această strategie face posibil ca

un răspuns generat de primirea unor date să plece sper celălalt capăt icircn acelaşi segment cu

confirmarea

Observaţie deoarece este dificil de menţinut timere pentru fiecare confirmare diferenţa de

200ms este calculată de un timer global Din acest motiv modul efectiv de comportare poate fi

descris şi icircn felul următor cacircnd un segment nu conţine decacirct o confirmare el este pus icircntr-o

coadă ce va fi inspectată de un proces care din 200 icircn 200 ms trimite tot ce s-a acumulat icircn

coada

Footnotes

2

Acest comportament a fost propus de David D Clark icircn iulie 1982 icircn RFC 813

Algoritmul Nagle

Acest algoritm3 icircncearcă să icircmbunătăţească performanţele exploatacircnd următoarea caracteristică

foarte des icircntacirclnită icircn dialogul dintre două staţii dacă se icircncearcă trimiterea unor date de

dimensiune mică icircnsă există icircncă date neconfirmate de partener atunci ele sunt buffer-ate şi

trimise icircntr-un segment mai mare cacircnd soseşte confirmarea aşteptată Icircn acest fel se poate evita

generarea datagramelor mici (tinygrame) icircn situaţia unei legături lente Icircn cazul unei legături

rapide confirmările vor veni repede şi icircntacircrzierea introdusă de algoritm va neglijabilă

Există icircnsă şi cazuri icircn care acest algoritm duce la deprecierea performanţelor mesajele scurte

generate de mişcările mouse-ului icircn cazul folosirii unui server X Window sau utilizarea tastelor

care trimit mai mult de un caracter (secvenţe escape) Pentru a rezolva aceste inconveninte API-

ul de utilizare a TCP-ului trebuie să ofere o modalitate de a dezactiva acest algoritm (icircn sistemele

bazate pe sockeţi există icircn acest scop opţiunea TCP_NODELAY)

Footnotes

algoritm3

Algoritmul aparţinacircnd lui John Nagle a fost propus icircn ianuarie 1984 icircn RFC 896

Fereastra glisantă

Algoritmul implementat de TCP pentru a implementa transferul sigur de date este cunoscut icircn

teorie sub numele de Go-Back-N Icircn acest algoritm se utilizează numere de secvenţă pentru a

distinge pachetele icircntre ele şi o coadă (dimensiunea maximă a cozii reprezintă fereastra) de

pachetele a căror confirmare se aşteaptă Pachetele se icircmpart icircn 4 categorii

1 pachete trimis şi pentru care s-a primit confirmare

2 pachete trimise şi pentru care se aşteaptă icircncă confirmarea

3 pachete care nu au fost trimise icircncă dar care nu depăşesc limitele ferestrei şi deci pot fi

trimise

4 pachete care icircncă nu au fost trimite şi care nici nu vor putea fi trimise decacirct după ce au

fost trimise toate pachetele din categoria 3 şi s-au primit o parte din confirmările la

pachetele din categoria 2

Dacă confirmările pentru pachetele din categoria 2 icircntacircrzie prea mult (un mecanism de timer-e

informează asupra acestui lucru) atunci ele vor fi retrimise Icircn versiunea iniţială TCP-ul nu

permitea decacirct confirmări pozitive ceea ce icircnseamnă că avansarea ferestrei se va icircmpotmoli la

segmentele neconfirmate Cum se poate evita aceasta situaţie vom discuta icircn detaliu icircn capitolele

următoare O soluţie foarte radicală o constituie introducerea de confirmări selective (acest lucru

este realizat de RFC 2018 din octombrie 1996) Această modifică face ca TCP-ul actual să fie un

hibrid de Go-Back-N şi Selective Repeat

Deoarece dimensiunea ferestrei este anunţată la fiecare segment un client lent poate ca pe măsură

ce trimite confirmările să informeze despre progresul icircnregistrat la livrarea datelor următorului

nivel (aplicaţie) Dacă datele vin prea repede pentru viteza cu care clientul procesează datele

fereastra fereastra se va dimiua şi chiar icircnchide (acest lucru se realizează anunţacircnd o fereastră de

dimensiune zero) Cum se realizează efectiv redeschiderea vom analiza icircntr-un capitol viitor

Slow start

Un transfer de date TCP poate să icircnceapă prin transmiterea de segmente pacircnă la umplerea

icircntregii ferestre după care fie se primesc confirmări care vor permite unor noi pachete să fie

trimise fie vor expira timer-ele de retransmisie şi se va icircncepe retrimiterea pachetelor de la

icircnceputul ferestrei Din păcate un astfel de comportament poate duce la pomparea icircn reţea a unui

număr de pachete prea mare pentru capacitatea disponibilă efectiv icircnrăutăţind congestia Pentru

a evita acest lucru s-a propus următoarea soluţie4 iniţial se trimite un segment după primirea

confirmării lui se trimit două segmente după sosirea confirmărilor pentru ele se trimit patru

segmente şi aşa mai departe La un moment dat fie vor icircncepe să se piardă segmente (un indiciu

că s-a atins capacitatea maximă a canalului) fie se va umple fereastra pe care o anunţă cel care

primeşte Trebuie să remarcam că datorită creşterii exponenţiale a numărului de segmente se va

atinge destul de repede una din cele două situaţii

Modalitatea efectivă de implementare a acestui algoritm are la bază utilizarea unei ferestre de

congestie (congestion window cwnd) care este iniţializată cu dimensiunea unui segment (cwnd

se calculează icircn octeţi) şi la fiecare pas este dublată fereastra efectivă din cadrul căreia se pot

trimite segmente este dată de minimul dintre ultima fereastra comunicată de partener şi cwnd

Footnotes

soluţie4

Soluţia aparţine lui V Jacobson şi a fost prezentată icircn 1988 la conferinţă ACM

SIGCOMM-88

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Deoarece TCP trebuie să funcţioneze icircn condiţii variate de latenţă modul icircn care se face

retransmiterea trebuie să fie cacirct mai flexibil (şi simplu icircn acelaşi timp pentru a introduce un

overhead cacirct mai mic) Timpul cacirct se aşteaptă venirea unei confirmări (retransmission timeout

RTO) este calculat prin cronometrarea timpului care icirci ia unui segment trimis să fie confirmat

Pentru o anumită conexiune se cronometrează cacircte un singur segment la un moment dat iar pe

baza RTT-ului măsurat se actualizează valoare RTO-ului

Icircn RFC 793 formula de calcul a RTO-ului este următoarea

unde este ultimul RTT măsurat este o estimare ponderată pentru RTT este un coeficient

de ponderare care icircn general are valoarea iar este un coeficient cu o valoare recomandată

de După cum se poate observa icircn valoarea lui este inclusă icircn mare măsură vechea valoarea

Icircn acest fel ajustarea RTT-ului se face treptat Din păcate acest mod de calcul nu funcţionează

bine la variaţii mari ale RTT-ului ducacircnd la creşterea numărului de retransmisii exact atunci

cacircnd fenomenul de congestie icircncepe să apară

Pentru a remedia aceste neajunsuri V Jacobsen a propus icircn 1988 o nouă metodă de calcul o

metodă care ţine seama seamă şi de modul icircn care variază diferenţa dintre RTT-uri Formulele

folosite sunt următoarele

unde este un estimare pentru media RTT-urilor este o estimare pentru abaterea RTT-urilor

faţă de medie (o aproximaţie suficientă pentru abaterea pătratică medie care icircnsă este mult mai

costisitor de calculat) este diferenţa dintre RTT-ul măsurat ( ) şi estimarea curentă ( )

Coeficientul cu care este actualizată estimarea curentă are valoarea de iar cel cu care este

actualizat estimarea abaterii este La stabilirea unei conexiuni valorile pentru şi sunt

alese astfel icircncacirct să rezulte un RTT de secunde şi un de 3 secunde (aceste recomandări

sunt făcute de RFC 1122)

Dacă pentru un anumit segment nu se primeşte confirmarea icircn intervalul indicat de el va fi

retrimis şi noul este dublat Valoarea maximă admisă pentru este de 240 secunde

Deoarece icircn cazul retrimiterilor nu se poate determina cu exactitate căruia din segmentele trimise

aparţine confirmarea actualizarea estimărilor este amacircnată pacircnă cacircnd se reuşeşte trimiterea

corectă (s-a primit confirmare) fără retransmitere(``din prima) a unui segment Acest artificiu

(deloc neimportant) care permite evitarea actualizarea eronată a estimărilor este cunoscut sub

numele de algoritmul lui Karn şi a fost propus icircn 1987 de P Karn şi C Partridge

Evitarea congestiei

Dacă cei doi parteneri care comunică prelucrează datele suficient de repede şi vor să transfere un

volum mare de date atunci limitarea de care se vor lovi este cea dată de viteza reţelei Din cauza

modului ``best-effort pe care IP-ul icircl oferă cacircnd canalul de comunicaţie este saturat o parte din

segmentele TCP se vor pierde Icircn mod poate paradoxal atacirct transmiţătorului cacirct şi receptorul se

pot afla icircn poziţia de a fi primii icircn detectarea pierderii unui segment Unul din indiciile de la

transmiţător care semnalează pierderea unui segment este (icircn mod evident) apariţia 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 icircn varianta iniţială nu

permite decacirct confirmări pozitive singurul lucru pe care receptorul icircl poate face este ca la fiecare

segment out-of-order primit să trimită o confirmare indicacircnd prin aceasta că la el continuă să

vină segmente icircnsă cel indicat de numărul de secvenţă de confirmare lipseşte Primirea acestor

confirmări multiple este al doilea mod icircn care transmiţătorul poate afla de apariţia congestiei

Algoritmul ce trebuie aplicat icircn momentul icircn care se detectează apariţia congestiei este cunoscut

sub numele de ``evitarea congestiei (congestion avoidence) Principiul care stă la baza lui este

ca la apariţia congestiei fie să se treacă la o incrementare liniară a dimensiunii ferestrei dacă

congestia a fost detectată ca urmare a primirii unor confirmări identice repetate fie să se reia

slow start-ul icircn cazul icircn care congestia s-a detectat prin expirarea unui timer de timeout

Implementarea acestui algoritm se bazează pe utilizarea unui nou contor (sstresh) care să indice

dimensiunea ferestrei de la care se trece de la incrementarea exponenţială la cea liniară

Algoritmul efectiv este următorul

1 la stabilirea unei noi conexiuni se pleacă cu sstresh iniţializat la valoare de 64K şi cwnd

la dimensiunea unui segment

2 trimiterea de segmente se face fără a depăşi minimul dintre fereastra publicată de partener

(pentru a nu depăşi capacitatea de procesesare a partenerului) şi cwnd-ul curent (pentru a

nu depăşi limita impusă de capacitatea reţelei)

3 la apariţia congestiei sstresh este setat la jumătatea valorii ferestrei curente (minimul

dintre fereastra anunţată de partener şi cwnd icircnsă cel puţin dimensiunea corespunzătoare

pentru două segmente) dacă congestia a fost detectată prin expirarea unui timer de

timeout atunci cwnd este iniţializat cu dimensiunea unui segment

4 la primirea unei confirmări incrementarea se face icircn două moduri icircn funcţie de relaţie icircn

care se află cwnd şi sstresh

1 dacă cwnd e mai mic sau egal cu sstresh se face incrementarea exponenţială

caracteristică slow start-ului (care de fapt nu e deloc slow icircn cazul de faţă)

2 dacă cwnd e mai mare ca sstresh atunci se face o incrementare cu dimensiunea

unui segment

Fast Retransmission Fast Recovery

După cum am văzut un receptor care primeşte segmente out-of-order va trimite transmiţătorului

confirmări duplicate Algoritmul denumit ``fast retransmission recomandă următoarele două

comportamenet

1 un receptor care detectează segmente out-of order trebuie să nu icircntacircrzie trimiterea de

confirmări (după cum am văzut icircn general confimările sunt icircntacircrziate micşora numărul de

pachete fără date care sunt transferate)

2 un transmiţător care care primeşte mai mult de trei confirmări duplicate trebuie să

retrimită segmentul indicat ca fiind neprimit de confirmările icircn cauză fără a aştepta

expirarea timer-ul de timeout

Algoritmul de ``fast recovery icircncearcă să optimizeze şi mai mult comportamentul

transmiţătorului care detectează un număr de trei sau mai multe confimări duplicate Mai exact el

recomandă trecerea la actualizarea liniară a ferestrei (congestion avoidance) Acest tip de

comportament se poate justifica prin următorul raţionament deoarece icircncă mai sunt transferate

date icircntre cei doi parteneri (şi acest lucru se icircntacircmplă sigur de vreme ce sosesc confirmări

duplicate icircn cazul acesta) icircnseamnă că transferul nu este afectat de o congestie severă şi prin

urmare trecerea la slow start nu e (icircncă) necesară (slow start-ul eliberează aproape complet

canalul deoarece cwnd este resetat la dimensiunea unui singur segment)

Cei doi algoritmi pot fi implementaţi icircn felul următor

1 cacircnd se detectează trei confirmări consecutive identice se setează sstresh la jumătate din

valoarea cwnd se retransmite segmentul care s-a pierdut şi se setează cwnd la valoarea

egală cu sstresh plus dimensiunea a trei segmente (acest lucru va face ca algoritmul de

incrementare a cwnd să treacă la incrementare liniară)

2 la fiecare confirmare duplicată care mai soseşte se incrementează cwnd se incrementează

cu dimensiunea unui segment

3 cacircnd icircncetează primirea de confirmări duplicate (segmentul retrimis a ajuns cu bine la

receptor şi s-a trimis o confirmare care acoperă segmentul care se pierduse iniţial) cwnd

este setat la valoarea sstresh

Sindromul ``Silly Window

Protocoalele bazate pe fereastră glisantă (cum este şi TCP-ul) pot să ajungă icircn situaţia deloc

fericită de trimite un număr mare de segmente mici icircn loc de segmente de dimensiune maximă

Acest tip de comportament este cunoscut sub numele de sindromul ``silly window

O modalitate prin care TCP-ul poate să cadă victimă acestui tip de comportament este

deschiderea de ferestre cu dimensiune foarte mică O altă situaţia nefericită este cea icircn care un

transmiţător este ``lacom şi trimite date indiferent de cacirct de mică este fereastra (după cum vom

vedea imediat uneori are sens şi un astfel de comportament) Algoritmul de evitare a acestor

neajunsuri este următorul

1 un receptor nu trebuie să anunţe deschideri de ferestre mici Mai exact nu se recomandă

anunţarea unei incrementări a ferestrei mai mică decacirct dimensiunea unui segment (MSS)

sau jumătate din buffer-ul aflat la dispoziţia receptorului oricare din ele e mai mică

2 un transmiţător va trimite date doar icircn următoarele cazuri

1 se poate trimite un segment icircntreg

2 se poate trimite jumătate din dimensiunea celei mai mari ferestre pe care

partenerul a publicat-o pacircnă acum

3 toate datele trimise pacircnă acum au fost confirmate sau algoritmul Nagle este

dezactivat şi se trimit toate datele care sunt icircn buffer-ul de trimitere

Cacircteva justificări cazul 2b tratează cazul icircn care partenerul anunţă ferestre mai mici decacirct

dimensiunea unui segment iar cazul 2c impune condiţiile respectării algoritmului Nagle după

cum se vede dacă algoritmul Nagle este activ şi s-au acumulat destul date mai exact cacirct

dimensiunea unui segment el va fi trimis chiar dacă există segmente neconfirmate Pentru

implementarea comportamentului impus de 2b un transmiţător trebuie să ţină evidenţa celei mai

mari ferestre pe care partenerul a anunţat-o Ţinacircnd seama că dimensiunea acestor buffer-e nu se

modifică acest mod de a icircncerca determinarea lor este suficient

O altă problemă legată tot de ferestre este cazul icircnchiderii acesteia Un mod icircn care s-ar putea

anunţa redeschiderea este trimiterea de către receptor a unei confirmări (duplicat) care să anunţe

redeschiderea la o anumită valoare a ferestrei Deoarece acest pachet nu trebuie confirmat icircn mod

special şi s-ar putea să se piardă se poate ajunge icircn situaţia icircn care receptorul a anunţat

redeschiderea ferestrei segmentul s-a pierdut iar transmiţătorul icircncă mai icircl mai aşteaptă pentru a

putea continua transferul Rezolvarea la această problemă s-a făcut prin impunerea unui alt

comportament

1 transmiţătorul va trimite segmente cu dimensiunea datelor de un octet prin care sondează

deschiderea ferestrei intervalul la care se sondează redeschiderea ferestrei se dublează

(exponenţial backoff) icircn RFC 793 dimensiunea maximă recomandată este de 2 minute

icircnsă icircn RFC 1122 se specifică că maximul este acelaşi cu cel din cazul retransmisiei (240

secunde)

2 receptorul trebuie să refuze aceste pachete răspunzacircnd cu segmente de confirmare care

indică neprimirea octetului respectiv

Observaţie timer-ul special necesar pentru implementare la transmiţător a comportamentului de mai sus este cunoscut sub numele de ``TCP Persistent Timer Numele este justificat de faptul că sondarea deschiderii se va face pacircnă cacircnd fie fereastra se deschide fie conexiunea se icircntrerupe TCP Keepalive Timer

Un lucru interesant despre TCP este faptul că dacă nivelele superioare nu comunică nimic icircntre

ele pentru o perioadă lungă 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 icircn care au trecut cu succes de faza stabilirii legăturii Dacă nivelurile

inferioare (reţeaIP fizic) devin temporar indisponibile cacirct tip cei doi nu vor să comunice atunci

acest lucru nu va perturba icircn nici un fel activitatea şi acest lucru este acceptabil Problemele

icircncep să apară icircn momentul icircn care cei doi doresc să comunice şi nivelele inferioare nu mai

permit acest lucru Evident că cel care va dori să comunice ceva va detecta icircntreruperea legăturii

şi va icircnchide conexiunea Ce se icircntacircmplă icircnsă dacă celălalt capăt nu are nimic de comunicat (de

exemplu este un server care oferă anumite servicii) Pentru el legătura va fi icircn continuare activă

şi icircn general anumite resurse vor fi rezervate pentru aceasta Rezolvarea acestei situaţii este dată

de introducerea unei mecanism de sondare a stării legăturii pe baza unui timer (TCP Keepalive

Timer) care se declanşează din două icircn două ore La fiecare expirare a timer-ului se trimite un

segment fără date care confirmă datele primite pacircnă atunci Răspunsul care trebuie primit este tot

un segment fără date care confirmă datele primite de partener (practic o re-publicare a stării celor

doi parteneri) Dacă răspunsul nu este primit timp de 75 secunde atunci segmentul va fi retrimis

Dacă după 10 astfel de icircncercări tot nu s-a primit nici un răspuns atunci conexiunea se va

considera terminată şi se va anunţa nivelul superior asupra acestui lucru

Observaţii

dacă o staţie primeşte segmente de keepalive despre conexiuni care nu mai sunt active

(de exemplu a fost resetat) atunci va răspunde cu segmente de reset (acesta e un procedeu

standard)

RFC 1122 specifică că facilitatea de keepalive trebuie activată icircn mod explicit

3 Studii de caz

Subsections

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

1 Fragmentarea pachetelor UDP

Deoarece UDP-ul este un serviciu fără conexiune toate datele pe care le primeşte de la nivelul

superior sunt icircncapsulate icircntr-o singură datagramă UDP care apoi va forma un pachet IP Dacă

pachetul IP astfel obţinut este prea mare atunci mecanismele IP de fragmentare icircl vor sparge icircn

bucăţi Exemplul următor icircncearcă să studieze exact acest fenomen

Pe maşina athos rulează un server de UDP pe portul 50007 Pe o altă maşină frodo aflată icircn

reţeaua locală este rulat un client care poate fi configurat să trimită un pachet UDP de o anumită

lungime Pentru a putea observa ce se icircntacircmplă pe athos este rulat tcpdump

Deoarece MTU-ul pentru o reţea Ethernet este icircn general 1500 şi antetul IP plus cel UDP ocupă

20 + 8 = 28 octeţi o datagramă UDP de dimensiune 1472 ar trebui sa fie trimisă nefragmentată

Pentru siguranţă folosind clientul de pe athos s-a trimis mai icircntacirci o datagramă UDP cu 1471

octeţi de date şi apoi icircncă una cu 1472 Pentru ambele tcpdump a indicat trimiterea lor fără

fragmentare

182556721144 frodonoi33274 gt athosnoi50007 udp 1471 (DF) (ttl 64 id

51481 len 1499)

182559846764 frodonoi33274 gt athosnoi50007 udp 1472 (DF) (ttl 64 id

51793 len 1500)

La o dimensiune de 1473 ar trebui ca trimiterea să genereze două pachete IP unul care să

conţină primii antetul UDP plus primii 1472 octeţi de date şi icircncă un pachet IP care conţine un

singur octet Iată ce indică tcpdump-ul

182605705813 frodonoi gt athosnoi udp (frag 3627411480) (ttl 64 len

21)

182605706116 frodonoi33274 gt athosnoi50007 udp 1473 (frag

3627414800+) (ttl 64 len 1500)

Intr-adevăr au fost generate două pachete IP

primul conţine doar un singur octet de date şi reprezintă ultimul fragment (bitul de more

fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest

lucru) care a fost spartă icircn bucăţi deplasamentul octetului primit in datagrama originală

este 1480

al doilea pachet este primul fragment din datagrama UDP şi conţine antetul UDP (din

cauza asta datele efective ocupă doar 1480 octeţi) deplasamentul este 0 şi bitul de more

fragments este setat (acest lucru este indicat de semnul ``+ de după deplasament)

După cum se poate observa ambele pachete poartă acelaşi număr de identificare (36274) Acest

lucru icircmpreună cu informaţiile date de flag-ul more fragments permite reconstrucţia la

destinaţie a datagramei UDP originale O problemă a acestui mod de fragmentare e că icircn cazul

pierderii unui fragment icircntreaga datagramă va fi compromisă şi va trebui retrimisă icircn icircntregime

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 3: udp tcp

1 UDP

Subsections

1 Caracteristici UDP

2 Formatul pachetelor UDP

1 Caracteristici UDP

UDP (User Datagram Protocol) este un protocol de nivel transport construit special pentru a oferi

un serviciu de comunicare cacirct mai simplu peste IP Specificaţiile protocolului au fost publicate icircn

1980 icircn RFC-ul cu numărul 7681

Cacircteva caracteristici ale UDP-ului sunt

este un serviciu de tip datagramă cererile de trimitere de date primite de la nivelul

superior sunt tratate independent

comunicarea are loc fără stabilirea unei legături (conection-less) nu există mecanisme de

stabilire şi terminare a unei conexiuni deoarece toate datele sunt trimise icircn cadrul unui

singur pachet IP care eventual va fi supus fragmentării

nu se garantează ajungerea ala destinaţie a datelor (best effort) ajungerea la destinaţie nu

este anunţată sursei

datele transportate sunt protejate de o sumă de control (introdusă ca opţională iniţial ea

este trecută ca necesară(must) icircn RFC 1122 care stabileşte modul de comportare al

clienţilor icircn Internet)

overhead-ul introdus este minim doar 8 octeţi

Cacircteva utilizări tipice ale UDP-ului

servicii de rezolvare a numelor (DNS) deoarece icircntrebările şi răspunsurile 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 fişiere (NFS) deoarece acest tip de aplicaţii sunt icircn general rulate icircn reţele

locale cu performanţe ridicate care nu necesită mecanismele TCP

managementul reţelei (SNMP)

protocoale de rutare (RIP)

Footnotes

7681

RFC 768 are nici mai mult nici mai puţin decacirct 3 pagini nu conţine cuprins dar are o listă

de 5 referinţe bibliografice

2 Formatul pachetelor UDP

Datagramele UDP sunt formate dintr-un antet (figura 71) urmat de datele care se doresc

transmise (dacă există)

Figura 71 Structura unei datagrame UDP

Antetul cuprinde

port sursă - 16 biţi

Icircmpreună cu adresa IP a sursei acest număr identifică icircn mod unic locul de unde a fost

trimis datagrama UDP

port destinaţie - 16 biţi

Icircmpreună cu adresa IP a destinaţiei acest număr identifică icircn mod unic destinaţia dorită

pentru datagrama UDP

lungimea pachetului UDP - 16 biţi

Lungimea minimă măsoară datagrama UDP cu tot cu antent şi prin urmare are o valoare

minimă de 8 octeţi

sumă de control - 16 biţi

Suma de control acoperă icircntreg pachetul UDP cacirct şi un pseudo antet de 12 octeţi format

din

adresa IP a sursei - 32 biţi

o adresa IP a destinaţiei - 32 biţi

8 biţi de zero pentru aliniere

numărul protocolului UDP (17) reprezentat pe 8 biţi

lungimea pachetului UDP - 16 biţi

Deoarece suma de control necesită icircn calculul ei un număr multiplu de 16 octeţi la

sfacircrşitul datelor se adaugă un număr potrivit de octeţi de zero Dacă suma este 0 atunci ea

va fi stocată ca 65535 (toţi biţii pe 1) Un 0 icircn cacircmpul de sumei de control indică faptul

că suma de control nu a fost calculată Observaţie chiar dacă un client are inhibat (icircn

mod explicit) calcului sumei de control el este obligat să verifice suma pachetelor care

sosesc şi au suma calculată

2 TCP

Subsections

1 Caracteristici TCP

2 Formatul pachetelor TCP

3 Iniţierea şi terminarea unei conexiuni TCP

o Protocolul de iniţiere

1 Deschiderea simultană

o Protocolul de terminare

2 Terminarea simultană

3 Resetarea conexiunii

o Diagrama de stări

4 Controlul fluxului

o Icircntacircrzierea confirmărilor

o Algoritmul Nagle

o Fereastra glisantă

o Slow start

o Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

o Evitarea congestiei

o Fast Retransmission Fast Recovery

o Sindromul ``Silly Window

o TCP Keepalive Timer

1 Caracteristici TCP

Deoarece protocolul IP este de tip datagramă utilizarea lui direct icircn aplicaţii care in general au

nevoie de conexiuni sigure este mult prea anevoioasă Din aceste motive peste IP a fost construit

un alt protocol TCP (transimission control protocol) care corectează aceste probleme Prima

definire se găseşte icircn RFC-ul cu numărul 793 şi datează din septembrie 1981 Din cauza deselor

congestii apărute icircn 1986 algoritmul care stă la baza TCP-ului este reanalizat şi icircn octombrie

1989 icircn RFC-ul cu numărul 1122 este publicată o nouă specificare mult mai eficientă şi

neambiguă a TCP-ului Noi probleme legate de viteze mari sunt tratate icircn RFC-ul 1323 iar icircn

2018 TCP-ul este extins pentru a permite confirmările selective (selective acknowledge) Seria

de RFC-urie fundamentale este icircncheiată de apariţia icircn 1989 a RFC-ului cu numărul 2581 Icircn el

se specifică foarte strict comportamentul care este permis pentru o implementare de TCP

Alături de protocolul UDP TCP se situează pe nivelul transport icircn ierarhia de protocoale deci

icircntre nivelul aplicaţie şi nivelul reţea Dar cu toate că se bazează pe acelaşi protocol (IP) ca şi

UDP TCP furnizează către nivelul aplicaţie cu totul alt tip de servicii servicii orientate-

conexiune sigure de tip flux de octeţi

Termenul de orientat-conexiune presupune că icircntre cele două aplicaţii care comunică utilizacircnd

TCP trebuie să se stabilească o conexiune TCP icircnainte ca transferul de date să aibă loc Această

conexiune nu este efectiv una fizică ci virtuală asemănător cum se icircntacircmplă icircn sistemul de

telefonie clasică cineva formează un număr şi abia icircn momentul icircn care cealaltă persoană

răspunde se poate icircncepe conversaţia Fiind o conexiune host-la-host nu există noţiunile de

broadcast sau multicast

Transferul sigur de date este asigurat icircn următorul mod

Datele sunt icircmpărţite icircn bucăţi a căror dimensiune optimă e determinată de TCP spre

deosebire de UDP care trimite datagrame UDP corespunzătoare cu dimensiunea datelor

primite de la nivelul aplicaţie Unitatea de date trimisă de TCP către nivelul reţea poartă

numele de segment

Cacircnd TCP trimite un segment porneşte un timer şi dacă nu se primeşte confirmarea

segmentului respectiv icircntr-un anumit timp icircl retransmite

Icircn momentul icircn care se primeşte un segment TCP trimite o confirmare (din motive de

eficienţă aceasta poate fi amacircnată un anumit interval de timp)

Icircn headerul TCP este menţinută o sumă de control pentru detectarea modificărilor icircn date

Dacă se recepţionează un segment corupt TCP icircl ignoră urmacircnd să fie retransmis datorită

neprimirii confirmării

Deoarece segmentele TCP sunt transmise mai departe icircncapsulate icircn datagrame IP iar

acestea pot ajunge icircn orice ordine segmentele TCP pot ajunge icircn altă ordine decacirct cea icircn

care au fost trimise De aceea la destinaţie TCP-ul trebuie să se folosească de numere de

secvenţă pentru a reordona eventual segmentele icircnainte de a le livra către nivelul

aplicaţie De asemenea TCP trebuie să asigure ignorarea duplicatelor

TCP asigură controlul fluxului icircn condiţiile icircn care viteza de trimitere a datelor de la sursă

poate fi mult prea mare decacirct capacitatea de prelucrare de la destinaţie

Serviciul oferit de TCP este de tip flux de octeţi deoarece oferă garanţii că fluxul de date trimis

de sursă va fi livrat fără modificări la destinaţie Comparativ UDP-ul produce pentru fiecare

transfer cerut de nivelul aplicaţie un pachet IP (care ulterior poate fi supus fragmentării) care

dacă ajunge la destinaţie corect va fi livrat direct nivelului aplicaţie fără a garanta icircn vreun fel

ordinea

2 Formatul pachetelor TCP

Pachetele de date transmise de TCP segmentele sunt formate dintr-un antet (figura 72) de 20

octeţi urmat de datele primite de la nivelul aplicaţie Antetul poate uneori conţine şi o serie de

opţiuni caz icircn care poate ajunge la 60 octeţi

Figura 72 Structura unui segment TCP

Antetul unui segment TCP cuprinde

port sursă - 16 biţi pentru specificarea portului aplicaţiei transmiţătoare

port destinaţie - 16 biţi pentru specificarea portului aplicaţiei ce recepţionează segmentul

TCP

Aceste două porturi icircmpreună cu adresele ale sursei şi destinaţiei conţinute icircn antet-ul IP

identifică icircn mod unic conexiunea Pentru o pereche formată dintr-o adresă IP şi un port

se foloseşte adesea denumirea de socket (denumire introdusă icircn specificaţiile iniţiale ale

protocolului TCP icircn RFC 793)

număr de secvenţă - 32 biţi

Pentru a asigura un serviciu de tip flux de octeţi TCP numerotează fiecare octet de date

utilizacircnd un număr de secvenţă Numărul de secvenţă din cadrul antetului TCP specifică

destinaţiei care este primul octet din fluxul trimis La iniţierea unei conexiuni se setează

flag-ul SYN şi se alege aleator un număr de secvenţă de icircnceput utilizacircnd un generator de

numere de secvenţă ISN (Initial sequence number) Numărul de secvenţă al primului

octet de date va fi numărul generat ISN plus 1 deoarece pachetul de iniţiere (cu SYN

setat) consumă şi el un număr de secvenţă Se va vedea mai departe că şi flag-ul de

terminare a conexiunii FIN consumă şi el un număr de secvenţă

confirmare - 32 biţi

Reprezintă numărul de secvenţă al octetului de date pe care transmiţătorul confirmării se

aşteaptă să-l primească Astfel dacă s-a recepţionat octetul cu numărul de secvenţă x (icircn

numerotaţia sursei) pachetul de confirmare va avea flag-ul ACK setat şi va conţine

numărul de confirmare x + 1 Trimiterea unui ACK nu consumă un număr de secvenţă

deoarece atacirct acest cacircmp cacirct şi flag-ul ACK fac parte din antet şi după stabilirea

conexiunii ambele cacircmpuri devin active Acest mecanism nu permite confirmări selective

pentru că numărul de secvenţă specifică pacircnă unde s-au recepţionat date De exemplu

dacă la destinaţie au ajuns octeţii 1-1024 şi următorul segment primit conţine octeţii

2049-3072 nu se poate trimite confirmare pentru cel de-al doilea segment deci

confirmarea va cuprinde numărul de secvenţă 1025

lungimea antetului - 4 biţi

Specifică dimensiunea antetului ca număr de cuvinte de 32 de biţi (4 octeţi) Antetul

poate avea icircntre 20 şi 60 de octeţi deci valoarea acestui cacircmp va fi icircntre 5 (5 x 4 = 20

octeţi) şi 15 (15 x 4 = 60)

6 biţi rezervaţi pentru utilizări viitoare

6 biţi de control reprezentacircnd următoarele flag-uri ce pot fi setate simultan

o URG - cacircmpul urgent pointer este valid

o ACK - cacircmpul de confirmare este valid

o PSH - destinaţia trebuie să trimită datele către nivelul aplicaţie cacirct mai devreme

o RST - se doreşte resetarea conexiunii

o SYN - iniţierea conexiunii

o FIN - icircnchiderea conexiunii

dimensiunea ferestrei - 16 biţi

Reprezintă numărul de octeţi (icircncepacircnd cu numărul de secvenţă conţinut icircn cacircmpul de

confirmare) pe care destinaţia e dispusă să-l primească Este limitat la 65535 octeţi dar

cu toate că pare o limită destul de mare există situaţii cacircnd se doresc valori mult mai

mari Icircn acest scop se folosesc nişte opţiuni speciale descrise ceva mai tacircrziu care permit

scalarea ferestrei

suma de control - 16 biţi

Această sumă de control acoperă icircntregul segment TCP (atacirct datele cacirct şi antetul TCP) şi

spre deosebire de UDP este obligatoriu să fie completat de transmiţător şi verificat de

receptor Dar ca şi icircn cazul UDP-ului la calculul sumei de control se ia in considerare şi

o zona specială de 12 octeţi ce cuprinde pentru re-verificare cacircmpuri din antetul IP

(adresa IP a sursei şi a destinaţiei)[aici tre sa vina o referire la poza cu pseudo-antetu]

După adăugarea acestui pseudo-antet datele se icircmpart icircn cuvinte de 16 biţi icircn vederea

calculării sumei de control adăugacircndu-se eventual şi un octet de aliniere

urgent pointer - 16 biţi

Este utilizat pentru specificarea deplasamentului ultimului octet de date trimis icircn regim

urgent Astfel ultimul octet din secvenţa urgentă se obţine adunacircnd acest cacircmp la

numărul de secvenţă Ce icircnseamnă acest mod urgent de transmitere există situaţii icircn care

aplicaţiile vor să trimită date `neordonate` Să presupunem că aplicaţia a trimis către

nivelul transport o cantitate mare de date dar la un moment dat observă ceva icircn neregulă

şi doreşte să anuleze operaţia Dacă trimite o comandă de anulare aceasta va fi adăugată

la sfacircrşitul şirului de octeţi deci nu se va putea icircmpiedica ajungerea acestora la nivelul

aplicaţie de la receptor Activacircnd modul urgent datele urgente (comanda de anulare) vor

fi plasate la icircnceputul pachetului Aplicaţiile mai cunoscute care folosesc acest mod sunt

Telnet Rlogin şi FTP

opţiuni - pacircnă la 40 de octeţi (figura 73)

Cele mai utilizate opţiuni sunt

o Sfacircrşit de opţiuni (end of option) - 1 octet

Este utilizat pentru alinierea datelor conţinute icircn cacircmpul de opţiuni Nu poate fi

utilizat decacirct o singură dată marcacircndu-se astfel sfacircrşitul opţiunilor şi icircnceperea

datelor efective Dacă pentru alinierea la un cuvacircnt de 32 de biţi e nevoie de mai

mult de 1 byte se va utiliza opţiunea no operation Orice apare după această

opţiune pacircnă la icircnceputul cuvacircntului următor de 32 de biţi e ignorat

o no operation - 1 octet

Utilizat pentru alinierea la cuvinte de 32 de biţi

o Dimensiunea maximă a segmentului (Maximum Segment Size (MSS)) - 16 biţi

Icircn ciuda denumirii defineşte lungimea maximă a datelor nu dimensiunea

icircntregului segment Poate lua valori icircntre 0 şi 65535 valoarea implicită fiind 536

Această opţiune e valabilă doar icircn pachetele de iniţiere a conexiunii (cele cu flag-

ul SYN setat) fiecare parte făcacircnd cunoscută dimensiunea maximă a datelor

dispusă să le primească icircntr-un pachet Icircn principiu cu cacirct această valoarea e mai

mare e mai bine (deoarece se recuperează din spaţiul ocupat de antetele TCP şi

IP) pacircnă cacircnd apare fragmentarea Valoarea maximă la care se poate seta este

MTU (Maximum Transfer Unit) minus dimensiunea antetului IP şi TCP (1460

octeţi icircn cazul Ethernet)

o Factor de scalare a ferestrei (Window scale factor) - 1 octet

Pentru situaţiile icircn care se doreşte utilizarea unei ferestre mai mare de 65535 bytes

se poate utiliza acest cacircmp pentru mărirea dimensiunii ferestrei Noua dimensiune

va fi Chiar dacă

factorul de scalare poate fi maxim 255 icircn cazul TCPIP el nu poate depăşi

valoarea 16 deoarece dimensiunea maximă a ferestrei nu poate fi mai mare decacirct

valoarea celui mai mare număr de secvenţă ( )

Acest factor se poate seta doar la iniţierea conexiunii Icircn timpul transferului de

date se poate modifica dimensiunea ferestrei dar factorul de scalare rămacircne

acelaşi Dacă cel care a iniţiat conexiunea a trimis icircn segmentul de iniţiere şi acest

factor dar icircn pachetul cu ACK destinatarul nu şi-a trimis şi el factorul atunci se la

considera 0 icircn ambele direcţii Invers dacă cel care solicită deschiderea

conexiunii nu setează factorul destinaţia nu va putea seta factorul de scalare

o Timestamp - 10 octeţi

Utilizat pentru reţinerea timpului icircn vederea calculării RTT (Round Trip Time)

Cacircmpul timestamp e completat de sursă icircn momentul trimiterii segmentului La

destinaţie valoarea este reţinută şi copiată icircn cacircmpul timestamp echo reply al

pachetului cu confirmarea RTT-ul este calculat de sursă făcacircnd diferenţa dintre

timpul curent şi această valoare

Figura Opţiuni TCP

3 Iniţierea şi terminarea unei conexiuni TCP

TCP este un protocol orientat conexiune deci presupune stabilirea unei căi virtuale icircntre sursă şi

destinaţie

Subsections

Protocolul de iniţiere

o 1 Deschiderea simultană

Protocolul de terminare

o 2 Terminarea simultană

o 3 Resetarea conexiunii

Diagrama de stări

Protocolul de iniţiere

Modul de transmisie icircn cazul protocolului TCP este full-duplex deci sunt transmise date

simultan icircn ambele direcţii Aceasta presupune că cel care iniţiază conexiunea trebuie să

primească aprobarea celuilalt capăt icircnainte de icircnceperea transferului de date sursa icircşi anunţă

intenţia de a iniţia o conexiune destinaţia trimite un pachet cu confirmarea cererii şi un pachet de

iniţiere a conexiunii de la el la sursă iar apoi sursa confirmă cererea primită de la destinaţie Paşii

2 şi 3 pot fi realizaţi prin trimiterea unui singur pachet de aceea protocolul de iniţiere este

cunoscut sub numele de three-way handshake

Icircn cadrul protocolului de iniţiere există 2 tipuri de cereri de iniţiere cerere activă (active open)

iniţiată de clientul ce doreşte să stabilească conexiunea cu serverul şi cerere pasivă (passive

open) din partea serverului

Cei 3 paşi sunt

1 Clientul trimite un segment cu flag-ul SYN setat şi care conţine portul sursă portul de la

destinaţie şi numărul de secvenţă generat iniţial (ISN) de la care se vor numerota octeţii

de la client către server Opţional se pot stabili parametrii conexiunii prin setarea lungimii

maxime a segmentelor (MSS) dispus să le primească de la server factorului de scalare a

ferestrei Acest prim segment nu conţine nici un parametru de confirmare şi de asemenea

nu are rost să conţine să seteze dimensiunea ferestrei

2 Al doilea segment e trimis de server şi are un rol dublu confirmă segmentul primit de la

client prin setarea flag-ului ACK şi completează numărul de secvenţă cu numărul de

secvenţă primit plus 1 şi al doilea rol iniţializează conexiunea de la el către client prin

setarea flag-ului SYN şi generarea unui număr de secvenţă iniţial ce va fi folosit icircn

numerotarea octeţilor de la server spre client Pe lacircngă aceasta trebuie să conţină

dimensiunea ferestrei şi opţional poate seta factorul de scalare şi dimensiunea maximă a

segmentului acceptat

3 Clientul trimite un segment cu confirmarea cererii din partea serverului (ACK setat +

completează numărul confirmat cu numărul de secvenţa primit + 1) Ca şi icircn cazul

pasului 2 trebuie să seteze dimensiunea ferestrei Acest pachet poate conţine date

Subsections

1 Deschiderea simultană

1 Deschiderea simultană

Se poate icircntacircmpla ca uneori cele două capete care vor să comunice să icircncerce să stabilească

conexiunea simultan Icircn acest caz după ce fiecare a trimis segmentul de iniţiere (iniţiere activă)

ambele vor trimite un segment cu SYN + ACK şi se va stabili o singură conexiune nu două

Protocolul de terminare

Oricare dintre cele două părţi poate solicita icircnchiderea conexiunii dar conexiunea fiind full-

duplex transferul de date icircn celălalt sens poate continua (această situaţie e denumită half-close)

O icircnchidere completă a unei conexiuni TCP presupune următorii paşi

1 Clientul trimite un segment cu flag-ul FIN activat solicitacircnd icircnchiderea conexiunii

2 Serverul trimite un segment ACK confirmacircnd primirea cererea Numărul de confirmare

se completează normal ca numărul de secvenţă primit + 1

3 Serverul continuă să trimită date către client şi cacircnd doreşte să icircnchidă şi el conexiunea

trimite un segment cu FIN activat

4 Clientul trimite un pachet ACK confirmacircnd icircnchiderea conexiunii

Cel care iniţiază primul procedura de icircnchidere (trimite primul FIN) realizează o icircnchidere activă

(active close) iar celălalt capăt o icircnchidere pasivă (passive close) Icircn mod normal cel care

realizează iniţierea activă va fi primul ce va trimite FIN dar oricare dintre cei doi poate icircnchide

activ conexiunea

Subsections

2 Terminarea simultană

3 Resetarea conexiunii

2 Terminarea simultană

Icircn mod similar cu deschiderea simultană există posibilitatea ca ambele capete ale conexiunii TCP

să iniţieze simultan procedura de icircnchidere a conexiunii Icircn acest caz ambele părţi vor trimite

FIN şi vor aştepta primirea unui ACK Icircn continuare fiecare va primi cererea de terminare şi va

trimite ACK Se observă că numărul de segmente transferate pentru realizarea icircnchiderii

conexiunii (4 segmente) este acelaşi ca la terminarea normală

3 Resetarea conexiunii

Există situaţii icircn care TCP doreşte resetarea conexiunii De exemplu dacă se solicită iniţierea

unei conexiuni la un port inexistent Icircn acest caz cealaltă parte va trimite un segment cu bitul

RST setat pentru a anula solicitarea O altă situaţie este atunci cacircnd se constată că celalalt capăt

al conexiunii nu răspunde un anumit timp (timeout)

Diagrama de stări

Toate evenimentele ce au loc icircn timpul stabilirii conexiunii transferului şi icircnchiderii conexiunii

pot fi rezumate printr-un automat finit cunoscut sub numele de diagrama de stări După cum

chiar numele sugerează este o maşină cu un număr limitat de stări O stare este păstrată pacircnă icircn

momentul apariţiei unui eveniment moment icircn care se poate trece icircn altă stare şisau efectua o

acţiune

Aceste stări posibile sunt (denumirile sunt asemănătoare cu cele utilizate de netstat) cele din

tabelul 71

Tabela Stările diagramei de stări TCP

Stare Descriere

CLOSED Nu există conexiune

LISTEN Serverul aşteaptă cereri de la clienţi

SYN_SENT Cerere de iniţiere (activă) a conexiunii Se

aşteaptă confirmarea

SYN_RCVD S-a primit o cerere de iniţiere conexiune

ESTABLISHED S-a stabilit conexiunea

FIN_WAIT_1 Aplicaţia a solicitat icircnchiderea conexiunii

FIN_WAIT_2 Serverul a acceptat icircnchiderea conexiunii

CLOSING Ambele părţi solicită simultan icircnchiderea

conexiunii

TIME_WAIT Conexiune icircnchisă dar se aşteaptă ca

pachetele retransmise să dispară

CLOSE_WAIT Serverul aşteaptă icircnchiderea dinspre partea

aplicaţiei

LAST_ACK Serverul a icircnchis conexiunea Aşteaptă

ultima confirmare

Icircn diagrama ilustrată icircn figura 74 putem observa 3 tipuri de tranziţii icircntre cele 11 stări tranziţii

ce corespund unei funcţionări normale pentru client (linii normale continue) pentru server (linii

normale icircntrerupte) şi tranziţii pentru situaţii nestandard (linii subţiri continue)

O comportarea normală pentru client presupune parcurgerea următoarelor stări CLOSED

SYN_SEND ESTABLISHED FIN_WAY_1 FIN_WAY_2 TIME_WAIT

Iniţial clientul TCP se află icircn starea CLOSED

Aşteptacircnd icircn starea CLOSED clientul poate primi de la aplicaţie o cerere de iniţiere

activă a unei conexiuni Trimite un segment SYN şi trece icircn starea SYN_SENT

Icircn starea SYN_SENT clientul aşteaptă de la server un segment ACK+SYN după care

trimite un ACK şi trece icircn starea ESTABLISHED Din acest moment poate icircncepe

transferul efectiv de date Clientul va rămacircne icircn această stare cacirct timp are de trimisprimit

date

Aflat icircn această stare clientul TCP poate primi din partea aplicaţiei o cerere de icircnchidere a

conexiunii Icircn acest caz va trimit un segment FIN şi trece icircn starea FIN_WAIT_1

Icircn această stare clientul aşteaptă ACK din partea serverului După ce-l primeşte

conexiunea icircntr-un sens se va icircnchide şi clientul trece icircn starea FIN_WAIT_2

Starea FIN_WAIT_2 durează pacircnă cacircnd primeşte cererea de icircnchidere a conexiunii FIN

din partea serverului Trimite ACK şi va trece icircn starea TIME_WAIT

Icircn această stare se va porni un timer cu valoarea setată la dublul timpului de viaţă estimat

pentru un segment de lungime maximă MSL (Maximum Segment Lifetime) Acest timer

permite retransmiterea ACK-ului icircn cazul icircn care acesta se pierde (celălalt capăt va da

timeout şi va retransmite segmentul FIN) Icircn tot acest time cei doi sockeţi (de la client şi

server) nu vor putea fi reutilizaţi Totodată pachetele icircntacircrziate care sosesc icircn această

perioadă sunt ignorate După expirarea acestui timer clientul revine icircn starea iniţială

CLOSED

Din punctul de vedere al unui server o comportare standard parcurge următoarele stări

CLOSED LISTEN SYN_RCVD ESTABLISHED CLOSE_WAIT şi LAST_ACK

Iniţial serverul TCP se află icircn starea CLOSED

Icircn această stare poate primi de la aplicaţia server o cerere de iniţiere activă şi trece icircn

starea LISTEN

Aflat icircn starea LISTEN serverului TCP poate recepţiona un segment SYN de la un client

TCP Icircn acest caz va trimite ACK+SYN şi va trece icircn starea SYN_RCVD

Icircn această stare serverul aşteaptă primirea confirmării de la client moment icircn care

conexiunea e stabilită icircn ambele sensuri şi se poate icircncepe transferul de date (starea

ESTABLISHED)

Clientul TCP poate solicita icircnchiderea conexiunii trimiţacircnd un segment FIN către server

Icircn acest caz serverul TCP trimite confirmarea şi trece icircn starea CLOSE_WAIT

Icircn această stare serverul aşteaptă să primească din partea programului server icircnchiderea

conexiunii moment icircn care va trimite către client un segment FIN şi trece icircn starea

LAST_ACK

Serverul aşteaptă primirea ultimei confirmări de la client după care revine icircn starea

CLOSED

Atacirct serverul cacirct şi clientul TCP se pot afla icircn oricare din cele 11 stări ale diagramei

Figura Diagrama de stări pentru TCP

4 Controlul fluxului

Dacă icircncă de la icircnceput s-a reuşit stabilirea formatului unui pachet TCP şi a modulului icircn care

trebuie să se facă icircnchiderea şi deschiderea unei conexiuni nu acelaşi lucru se poate spune şi

despre modul icircn care ar trebui să se realizeze controlul fluxului Ţinacircnd seama icircnsă că din 1989

(de cacircnd datează RFC-ul 2581 cel despre care am menţionat că specifică icircn mod clar modul icircn

care trebuie să se comporte o implementare de TCP) TCP-ul a rămas neschimbat putem să icircl

considerăm un rezultat important al domeniului reţelor de calculatoare

Icircn cele ce urmează vom icircnţelege prin controlul fluxului totalitatea algoritmilor care permit

atingerea unei viteze de transfer punct-la-punct cacirct mai mare pentru toate conexiunile existente

Icircn principal aceşti algoritmi stabilesc modul icircn care segmentele şi confirmările trebuie trimise şi

ce acţiuni trebuie executate icircn situaţiile icircn care răspunsurile aşteptate de la celălalt capăt icircntacircrzie

să vină

Subsections

Icircntacircrzierea confirmărilor

Algoritmul Nagle

Fereastra glisantă

Slow start

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Evitarea congestiei

Fast Retransmission Fast Recovery

Sindromul ``Silly Window

TCP Keepalive Timer

Icircntacircrzierea confirmărilor

O modalitate simplă de generare a confirmărilor este de a trimite cacircte una pentru fiecare segment

primit Această politică prezintă avantajul de a face comunicaţia self-clocking icircnsă este

ineficientă dacă segmentele care nu conţin decacirct confirmări sunt urmate la scurtă distanţă (cacircteva

zeci de milisecunde) de segmente ce conţin date efective Pentru a evita această situaţie se

procedează2 la icircntacircrzierea (200ms este o valoare uzuală icircn RFC 1122 se specifică o valoare

maximă de 500ms) a segmentelor care conţin doar confirmări Această strategie face posibil ca

un răspuns generat de primirea unor date să plece sper celălalt capăt icircn acelaşi segment cu

confirmarea

Observaţie deoarece este dificil de menţinut timere pentru fiecare confirmare diferenţa de

200ms este calculată de un timer global Din acest motiv modul efectiv de comportare poate fi

descris şi icircn felul următor cacircnd un segment nu conţine decacirct o confirmare el este pus icircntr-o

coadă ce va fi inspectată de un proces care din 200 icircn 200 ms trimite tot ce s-a acumulat icircn

coada

Footnotes

2

Acest comportament a fost propus de David D Clark icircn iulie 1982 icircn RFC 813

Algoritmul Nagle

Acest algoritm3 icircncearcă să icircmbunătăţească performanţele exploatacircnd următoarea caracteristică

foarte des icircntacirclnită icircn dialogul dintre două staţii dacă se icircncearcă trimiterea unor date de

dimensiune mică icircnsă există icircncă date neconfirmate de partener atunci ele sunt buffer-ate şi

trimise icircntr-un segment mai mare cacircnd soseşte confirmarea aşteptată Icircn acest fel se poate evita

generarea datagramelor mici (tinygrame) icircn situaţia unei legături lente Icircn cazul unei legături

rapide confirmările vor veni repede şi icircntacircrzierea introdusă de algoritm va neglijabilă

Există icircnsă şi cazuri icircn care acest algoritm duce la deprecierea performanţelor mesajele scurte

generate de mişcările mouse-ului icircn cazul folosirii unui server X Window sau utilizarea tastelor

care trimit mai mult de un caracter (secvenţe escape) Pentru a rezolva aceste inconveninte API-

ul de utilizare a TCP-ului trebuie să ofere o modalitate de a dezactiva acest algoritm (icircn sistemele

bazate pe sockeţi există icircn acest scop opţiunea TCP_NODELAY)

Footnotes

algoritm3

Algoritmul aparţinacircnd lui John Nagle a fost propus icircn ianuarie 1984 icircn RFC 896

Fereastra glisantă

Algoritmul implementat de TCP pentru a implementa transferul sigur de date este cunoscut icircn

teorie sub numele de Go-Back-N Icircn acest algoritm se utilizează numere de secvenţă pentru a

distinge pachetele icircntre ele şi o coadă (dimensiunea maximă a cozii reprezintă fereastra) de

pachetele a căror confirmare se aşteaptă Pachetele se icircmpart icircn 4 categorii

1 pachete trimis şi pentru care s-a primit confirmare

2 pachete trimise şi pentru care se aşteaptă icircncă confirmarea

3 pachete care nu au fost trimise icircncă dar care nu depăşesc limitele ferestrei şi deci pot fi

trimise

4 pachete care icircncă nu au fost trimite şi care nici nu vor putea fi trimise decacirct după ce au

fost trimise toate pachetele din categoria 3 şi s-au primit o parte din confirmările la

pachetele din categoria 2

Dacă confirmările pentru pachetele din categoria 2 icircntacircrzie prea mult (un mecanism de timer-e

informează asupra acestui lucru) atunci ele vor fi retrimise Icircn versiunea iniţială TCP-ul nu

permitea decacirct confirmări pozitive ceea ce icircnseamnă că avansarea ferestrei se va icircmpotmoli la

segmentele neconfirmate Cum se poate evita aceasta situaţie vom discuta icircn detaliu icircn capitolele

următoare O soluţie foarte radicală o constituie introducerea de confirmări selective (acest lucru

este realizat de RFC 2018 din octombrie 1996) Această modifică face ca TCP-ul actual să fie un

hibrid de Go-Back-N şi Selective Repeat

Deoarece dimensiunea ferestrei este anunţată la fiecare segment un client lent poate ca pe măsură

ce trimite confirmările să informeze despre progresul icircnregistrat la livrarea datelor următorului

nivel (aplicaţie) Dacă datele vin prea repede pentru viteza cu care clientul procesează datele

fereastra fereastra se va dimiua şi chiar icircnchide (acest lucru se realizează anunţacircnd o fereastră de

dimensiune zero) Cum se realizează efectiv redeschiderea vom analiza icircntr-un capitol viitor

Slow start

Un transfer de date TCP poate să icircnceapă prin transmiterea de segmente pacircnă la umplerea

icircntregii ferestre după care fie se primesc confirmări care vor permite unor noi pachete să fie

trimise fie vor expira timer-ele de retransmisie şi se va icircncepe retrimiterea pachetelor de la

icircnceputul ferestrei Din păcate un astfel de comportament poate duce la pomparea icircn reţea a unui

număr de pachete prea mare pentru capacitatea disponibilă efectiv icircnrăutăţind congestia Pentru

a evita acest lucru s-a propus următoarea soluţie4 iniţial se trimite un segment după primirea

confirmării lui se trimit două segmente după sosirea confirmărilor pentru ele se trimit patru

segmente şi aşa mai departe La un moment dat fie vor icircncepe să se piardă segmente (un indiciu

că s-a atins capacitatea maximă a canalului) fie se va umple fereastra pe care o anunţă cel care

primeşte Trebuie să remarcam că datorită creşterii exponenţiale a numărului de segmente se va

atinge destul de repede una din cele două situaţii

Modalitatea efectivă de implementare a acestui algoritm are la bază utilizarea unei ferestre de

congestie (congestion window cwnd) care este iniţializată cu dimensiunea unui segment (cwnd

se calculează icircn octeţi) şi la fiecare pas este dublată fereastra efectivă din cadrul căreia se pot

trimite segmente este dată de minimul dintre ultima fereastra comunicată de partener şi cwnd

Footnotes

soluţie4

Soluţia aparţine lui V Jacobson şi a fost prezentată icircn 1988 la conferinţă ACM

SIGCOMM-88

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Deoarece TCP trebuie să funcţioneze icircn condiţii variate de latenţă modul icircn care se face

retransmiterea trebuie să fie cacirct mai flexibil (şi simplu icircn acelaşi timp pentru a introduce un

overhead cacirct mai mic) Timpul cacirct se aşteaptă venirea unei confirmări (retransmission timeout

RTO) este calculat prin cronometrarea timpului care icirci ia unui segment trimis să fie confirmat

Pentru o anumită conexiune se cronometrează cacircte un singur segment la un moment dat iar pe

baza RTT-ului măsurat se actualizează valoare RTO-ului

Icircn RFC 793 formula de calcul a RTO-ului este următoarea

unde este ultimul RTT măsurat este o estimare ponderată pentru RTT este un coeficient

de ponderare care icircn general are valoarea iar este un coeficient cu o valoare recomandată

de După cum se poate observa icircn valoarea lui este inclusă icircn mare măsură vechea valoarea

Icircn acest fel ajustarea RTT-ului se face treptat Din păcate acest mod de calcul nu funcţionează

bine la variaţii mari ale RTT-ului ducacircnd la creşterea numărului de retransmisii exact atunci

cacircnd fenomenul de congestie icircncepe să apară

Pentru a remedia aceste neajunsuri V Jacobsen a propus icircn 1988 o nouă metodă de calcul o

metodă care ţine seama seamă şi de modul icircn care variază diferenţa dintre RTT-uri Formulele

folosite sunt următoarele

unde este un estimare pentru media RTT-urilor este o estimare pentru abaterea RTT-urilor

faţă de medie (o aproximaţie suficientă pentru abaterea pătratică medie care icircnsă este mult mai

costisitor de calculat) este diferenţa dintre RTT-ul măsurat ( ) şi estimarea curentă ( )

Coeficientul cu care este actualizată estimarea curentă are valoarea de iar cel cu care este

actualizat estimarea abaterii este La stabilirea unei conexiuni valorile pentru şi sunt

alese astfel icircncacirct să rezulte un RTT de secunde şi un de 3 secunde (aceste recomandări

sunt făcute de RFC 1122)

Dacă pentru un anumit segment nu se primeşte confirmarea icircn intervalul indicat de el va fi

retrimis şi noul este dublat Valoarea maximă admisă pentru este de 240 secunde

Deoarece icircn cazul retrimiterilor nu se poate determina cu exactitate căruia din segmentele trimise

aparţine confirmarea actualizarea estimărilor este amacircnată pacircnă cacircnd se reuşeşte trimiterea

corectă (s-a primit confirmare) fără retransmitere(``din prima) a unui segment Acest artificiu

(deloc neimportant) care permite evitarea actualizarea eronată a estimărilor este cunoscut sub

numele de algoritmul lui Karn şi a fost propus icircn 1987 de P Karn şi C Partridge

Evitarea congestiei

Dacă cei doi parteneri care comunică prelucrează datele suficient de repede şi vor să transfere un

volum mare de date atunci limitarea de care se vor lovi este cea dată de viteza reţelei Din cauza

modului ``best-effort pe care IP-ul icircl oferă cacircnd canalul de comunicaţie este saturat o parte din

segmentele TCP se vor pierde Icircn mod poate paradoxal atacirct transmiţătorului cacirct şi receptorul se

pot afla icircn poziţia de a fi primii icircn detectarea pierderii unui segment Unul din indiciile de la

transmiţător care semnalează pierderea unui segment este (icircn mod evident) apariţia 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 icircn varianta iniţială nu

permite decacirct confirmări pozitive singurul lucru pe care receptorul icircl poate face este ca la fiecare

segment out-of-order primit să trimită o confirmare indicacircnd prin aceasta că la el continuă să

vină segmente icircnsă cel indicat de numărul de secvenţă de confirmare lipseşte Primirea acestor

confirmări multiple este al doilea mod icircn care transmiţătorul poate afla de apariţia congestiei

Algoritmul ce trebuie aplicat icircn momentul icircn care se detectează apariţia congestiei este cunoscut

sub numele de ``evitarea congestiei (congestion avoidence) Principiul care stă la baza lui este

ca la apariţia congestiei fie să se treacă la o incrementare liniară a dimensiunii ferestrei dacă

congestia a fost detectată ca urmare a primirii unor confirmări identice repetate fie să se reia

slow start-ul icircn cazul icircn care congestia s-a detectat prin expirarea unui timer de timeout

Implementarea acestui algoritm se bazează pe utilizarea unui nou contor (sstresh) care să indice

dimensiunea ferestrei de la care se trece de la incrementarea exponenţială la cea liniară

Algoritmul efectiv este următorul

1 la stabilirea unei noi conexiuni se pleacă cu sstresh iniţializat la valoare de 64K şi cwnd

la dimensiunea unui segment

2 trimiterea de segmente se face fără a depăşi minimul dintre fereastra publicată de partener

(pentru a nu depăşi capacitatea de procesesare a partenerului) şi cwnd-ul curent (pentru a

nu depăşi limita impusă de capacitatea reţelei)

3 la apariţia congestiei sstresh este setat la jumătatea valorii ferestrei curente (minimul

dintre fereastra anunţată de partener şi cwnd icircnsă cel puţin dimensiunea corespunzătoare

pentru două segmente) dacă congestia a fost detectată prin expirarea unui timer de

timeout atunci cwnd este iniţializat cu dimensiunea unui segment

4 la primirea unei confirmări incrementarea se face icircn două moduri icircn funcţie de relaţie icircn

care se află cwnd şi sstresh

1 dacă cwnd e mai mic sau egal cu sstresh se face incrementarea exponenţială

caracteristică slow start-ului (care de fapt nu e deloc slow icircn cazul de faţă)

2 dacă cwnd e mai mare ca sstresh atunci se face o incrementare cu dimensiunea

unui segment

Fast Retransmission Fast Recovery

După cum am văzut un receptor care primeşte segmente out-of-order va trimite transmiţătorului

confirmări duplicate Algoritmul denumit ``fast retransmission recomandă următoarele două

comportamenet

1 un receptor care detectează segmente out-of order trebuie să nu icircntacircrzie trimiterea de

confirmări (după cum am văzut icircn general confimările sunt icircntacircrziate micşora numărul de

pachete fără date care sunt transferate)

2 un transmiţător care care primeşte mai mult de trei confirmări duplicate trebuie să

retrimită segmentul indicat ca fiind neprimit de confirmările icircn cauză fără a aştepta

expirarea timer-ul de timeout

Algoritmul de ``fast recovery icircncearcă să optimizeze şi mai mult comportamentul

transmiţătorului care detectează un număr de trei sau mai multe confimări duplicate Mai exact el

recomandă trecerea la actualizarea liniară a ferestrei (congestion avoidance) Acest tip de

comportament se poate justifica prin următorul raţionament deoarece icircncă mai sunt transferate

date icircntre cei doi parteneri (şi acest lucru se icircntacircmplă sigur de vreme ce sosesc confirmări

duplicate icircn cazul acesta) icircnseamnă că transferul nu este afectat de o congestie severă şi prin

urmare trecerea la slow start nu e (icircncă) necesară (slow start-ul eliberează aproape complet

canalul deoarece cwnd este resetat la dimensiunea unui singur segment)

Cei doi algoritmi pot fi implementaţi icircn felul următor

1 cacircnd se detectează trei confirmări consecutive identice se setează sstresh la jumătate din

valoarea cwnd se retransmite segmentul care s-a pierdut şi se setează cwnd la valoarea

egală cu sstresh plus dimensiunea a trei segmente (acest lucru va face ca algoritmul de

incrementare a cwnd să treacă la incrementare liniară)

2 la fiecare confirmare duplicată care mai soseşte se incrementează cwnd se incrementează

cu dimensiunea unui segment

3 cacircnd icircncetează primirea de confirmări duplicate (segmentul retrimis a ajuns cu bine la

receptor şi s-a trimis o confirmare care acoperă segmentul care se pierduse iniţial) cwnd

este setat la valoarea sstresh

Sindromul ``Silly Window

Protocoalele bazate pe fereastră glisantă (cum este şi TCP-ul) pot să ajungă icircn situaţia deloc

fericită de trimite un număr mare de segmente mici icircn loc de segmente de dimensiune maximă

Acest tip de comportament este cunoscut sub numele de sindromul ``silly window

O modalitate prin care TCP-ul poate să cadă victimă acestui tip de comportament este

deschiderea de ferestre cu dimensiune foarte mică O altă situaţia nefericită este cea icircn care un

transmiţător este ``lacom şi trimite date indiferent de cacirct de mică este fereastra (după cum vom

vedea imediat uneori are sens şi un astfel de comportament) Algoritmul de evitare a acestor

neajunsuri este următorul

1 un receptor nu trebuie să anunţe deschideri de ferestre mici Mai exact nu se recomandă

anunţarea unei incrementări a ferestrei mai mică decacirct dimensiunea unui segment (MSS)

sau jumătate din buffer-ul aflat la dispoziţia receptorului oricare din ele e mai mică

2 un transmiţător va trimite date doar icircn următoarele cazuri

1 se poate trimite un segment icircntreg

2 se poate trimite jumătate din dimensiunea celei mai mari ferestre pe care

partenerul a publicat-o pacircnă acum

3 toate datele trimise pacircnă acum au fost confirmate sau algoritmul Nagle este

dezactivat şi se trimit toate datele care sunt icircn buffer-ul de trimitere

Cacircteva justificări cazul 2b tratează cazul icircn care partenerul anunţă ferestre mai mici decacirct

dimensiunea unui segment iar cazul 2c impune condiţiile respectării algoritmului Nagle după

cum se vede dacă algoritmul Nagle este activ şi s-au acumulat destul date mai exact cacirct

dimensiunea unui segment el va fi trimis chiar dacă există segmente neconfirmate Pentru

implementarea comportamentului impus de 2b un transmiţător trebuie să ţină evidenţa celei mai

mari ferestre pe care partenerul a anunţat-o Ţinacircnd seama că dimensiunea acestor buffer-e nu se

modifică acest mod de a icircncerca determinarea lor este suficient

O altă problemă legată tot de ferestre este cazul icircnchiderii acesteia Un mod icircn care s-ar putea

anunţa redeschiderea este trimiterea de către receptor a unei confirmări (duplicat) care să anunţe

redeschiderea la o anumită valoare a ferestrei Deoarece acest pachet nu trebuie confirmat icircn mod

special şi s-ar putea să se piardă se poate ajunge icircn situaţia icircn care receptorul a anunţat

redeschiderea ferestrei segmentul s-a pierdut iar transmiţătorul icircncă mai icircl mai aşteaptă pentru a

putea continua transferul Rezolvarea la această problemă s-a făcut prin impunerea unui alt

comportament

1 transmiţătorul va trimite segmente cu dimensiunea datelor de un octet prin care sondează

deschiderea ferestrei intervalul la care se sondează redeschiderea ferestrei se dublează

(exponenţial backoff) icircn RFC 793 dimensiunea maximă recomandată este de 2 minute

icircnsă icircn RFC 1122 se specifică că maximul este acelaşi cu cel din cazul retransmisiei (240

secunde)

2 receptorul trebuie să refuze aceste pachete răspunzacircnd cu segmente de confirmare care

indică neprimirea octetului respectiv

Observaţie timer-ul special necesar pentru implementare la transmiţător a comportamentului de mai sus este cunoscut sub numele de ``TCP Persistent Timer Numele este justificat de faptul că sondarea deschiderii se va face pacircnă cacircnd fie fereastra se deschide fie conexiunea se icircntrerupe TCP Keepalive Timer

Un lucru interesant despre TCP este faptul că dacă nivelele superioare nu comunică nimic icircntre

ele pentru o perioadă lungă 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 icircn care au trecut cu succes de faza stabilirii legăturii Dacă nivelurile

inferioare (reţeaIP fizic) devin temporar indisponibile cacirct tip cei doi nu vor să comunice atunci

acest lucru nu va perturba icircn nici un fel activitatea şi acest lucru este acceptabil Problemele

icircncep să apară icircn momentul icircn care cei doi doresc să comunice şi nivelele inferioare nu mai

permit acest lucru Evident că cel care va dori să comunice ceva va detecta icircntreruperea legăturii

şi va icircnchide conexiunea Ce se icircntacircmplă icircnsă dacă celălalt capăt nu are nimic de comunicat (de

exemplu este un server care oferă anumite servicii) Pentru el legătura va fi icircn continuare activă

şi icircn general anumite resurse vor fi rezervate pentru aceasta Rezolvarea acestei situaţii este dată

de introducerea unei mecanism de sondare a stării legăturii pe baza unui timer (TCP Keepalive

Timer) care se declanşează din două icircn două ore La fiecare expirare a timer-ului se trimite un

segment fără date care confirmă datele primite pacircnă atunci Răspunsul care trebuie primit este tot

un segment fără date care confirmă datele primite de partener (practic o re-publicare a stării celor

doi parteneri) Dacă răspunsul nu este primit timp de 75 secunde atunci segmentul va fi retrimis

Dacă după 10 astfel de icircncercări tot nu s-a primit nici un răspuns atunci conexiunea se va

considera terminată şi se va anunţa nivelul superior asupra acestui lucru

Observaţii

dacă o staţie primeşte segmente de keepalive despre conexiuni care nu mai sunt active

(de exemplu a fost resetat) atunci va răspunde cu segmente de reset (acesta e un procedeu

standard)

RFC 1122 specifică că facilitatea de keepalive trebuie activată icircn mod explicit

3 Studii de caz

Subsections

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

1 Fragmentarea pachetelor UDP

Deoarece UDP-ul este un serviciu fără conexiune toate datele pe care le primeşte de la nivelul

superior sunt icircncapsulate icircntr-o singură datagramă UDP care apoi va forma un pachet IP Dacă

pachetul IP astfel obţinut este prea mare atunci mecanismele IP de fragmentare icircl vor sparge icircn

bucăţi Exemplul următor icircncearcă să studieze exact acest fenomen

Pe maşina athos rulează un server de UDP pe portul 50007 Pe o altă maşină frodo aflată icircn

reţeaua locală este rulat un client care poate fi configurat să trimită un pachet UDP de o anumită

lungime Pentru a putea observa ce se icircntacircmplă pe athos este rulat tcpdump

Deoarece MTU-ul pentru o reţea Ethernet este icircn general 1500 şi antetul IP plus cel UDP ocupă

20 + 8 = 28 octeţi o datagramă UDP de dimensiune 1472 ar trebui sa fie trimisă nefragmentată

Pentru siguranţă folosind clientul de pe athos s-a trimis mai icircntacirci o datagramă UDP cu 1471

octeţi de date şi apoi icircncă una cu 1472 Pentru ambele tcpdump a indicat trimiterea lor fără

fragmentare

182556721144 frodonoi33274 gt athosnoi50007 udp 1471 (DF) (ttl 64 id

51481 len 1499)

182559846764 frodonoi33274 gt athosnoi50007 udp 1472 (DF) (ttl 64 id

51793 len 1500)

La o dimensiune de 1473 ar trebui ca trimiterea să genereze două pachete IP unul care să

conţină primii antetul UDP plus primii 1472 octeţi de date şi icircncă un pachet IP care conţine un

singur octet Iată ce indică tcpdump-ul

182605705813 frodonoi gt athosnoi udp (frag 3627411480) (ttl 64 len

21)

182605706116 frodonoi33274 gt athosnoi50007 udp 1473 (frag

3627414800+) (ttl 64 len 1500)

Intr-adevăr au fost generate două pachete IP

primul conţine doar un singur octet de date şi reprezintă ultimul fragment (bitul de more

fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest

lucru) care a fost spartă icircn bucăţi deplasamentul octetului primit in datagrama originală

este 1480

al doilea pachet este primul fragment din datagrama UDP şi conţine antetul UDP (din

cauza asta datele efective ocupă doar 1480 octeţi) deplasamentul este 0 şi bitul de more

fragments este setat (acest lucru este indicat de semnul ``+ de după deplasament)

După cum se poate observa ambele pachete poartă acelaşi număr de identificare (36274) Acest

lucru icircmpreună cu informaţiile date de flag-ul more fragments permite reconstrucţia la

destinaţie a datagramei UDP originale O problemă a acestui mod de fragmentare e că icircn cazul

pierderii unui fragment icircntreaga datagramă va fi compromisă şi va trebui retrimisă icircn icircntregime

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 4: udp tcp

2 Formatul pachetelor UDP

Datagramele UDP sunt formate dintr-un antet (figura 71) urmat de datele care se doresc

transmise (dacă există)

Figura 71 Structura unei datagrame UDP

Antetul cuprinde

port sursă - 16 biţi

Icircmpreună cu adresa IP a sursei acest număr identifică icircn mod unic locul de unde a fost

trimis datagrama UDP

port destinaţie - 16 biţi

Icircmpreună cu adresa IP a destinaţiei acest număr identifică icircn mod unic destinaţia dorită

pentru datagrama UDP

lungimea pachetului UDP - 16 biţi

Lungimea minimă măsoară datagrama UDP cu tot cu antent şi prin urmare are o valoare

minimă de 8 octeţi

sumă de control - 16 biţi

Suma de control acoperă icircntreg pachetul UDP cacirct şi un pseudo antet de 12 octeţi format

din

adresa IP a sursei - 32 biţi

o adresa IP a destinaţiei - 32 biţi

8 biţi de zero pentru aliniere

numărul protocolului UDP (17) reprezentat pe 8 biţi

lungimea pachetului UDP - 16 biţi

Deoarece suma de control necesită icircn calculul ei un număr multiplu de 16 octeţi la

sfacircrşitul datelor se adaugă un număr potrivit de octeţi de zero Dacă suma este 0 atunci ea

va fi stocată ca 65535 (toţi biţii pe 1) Un 0 icircn cacircmpul de sumei de control indică faptul

că suma de control nu a fost calculată Observaţie chiar dacă un client are inhibat (icircn

mod explicit) calcului sumei de control el este obligat să verifice suma pachetelor care

sosesc şi au suma calculată

2 TCP

Subsections

1 Caracteristici TCP

2 Formatul pachetelor TCP

3 Iniţierea şi terminarea unei conexiuni TCP

o Protocolul de iniţiere

1 Deschiderea simultană

o Protocolul de terminare

2 Terminarea simultană

3 Resetarea conexiunii

o Diagrama de stări

4 Controlul fluxului

o Icircntacircrzierea confirmărilor

o Algoritmul Nagle

o Fereastra glisantă

o Slow start

o Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

o Evitarea congestiei

o Fast Retransmission Fast Recovery

o Sindromul ``Silly Window

o TCP Keepalive Timer

1 Caracteristici TCP

Deoarece protocolul IP este de tip datagramă utilizarea lui direct icircn aplicaţii care in general au

nevoie de conexiuni sigure este mult prea anevoioasă Din aceste motive peste IP a fost construit

un alt protocol TCP (transimission control protocol) care corectează aceste probleme Prima

definire se găseşte icircn RFC-ul cu numărul 793 şi datează din septembrie 1981 Din cauza deselor

congestii apărute icircn 1986 algoritmul care stă la baza TCP-ului este reanalizat şi icircn octombrie

1989 icircn RFC-ul cu numărul 1122 este publicată o nouă specificare mult mai eficientă şi

neambiguă a TCP-ului Noi probleme legate de viteze mari sunt tratate icircn RFC-ul 1323 iar icircn

2018 TCP-ul este extins pentru a permite confirmările selective (selective acknowledge) Seria

de RFC-urie fundamentale este icircncheiată de apariţia icircn 1989 a RFC-ului cu numărul 2581 Icircn el

se specifică foarte strict comportamentul care este permis pentru o implementare de TCP

Alături de protocolul UDP TCP se situează pe nivelul transport icircn ierarhia de protocoale deci

icircntre nivelul aplicaţie şi nivelul reţea Dar cu toate că se bazează pe acelaşi protocol (IP) ca şi

UDP TCP furnizează către nivelul aplicaţie cu totul alt tip de servicii servicii orientate-

conexiune sigure de tip flux de octeţi

Termenul de orientat-conexiune presupune că icircntre cele două aplicaţii care comunică utilizacircnd

TCP trebuie să se stabilească o conexiune TCP icircnainte ca transferul de date să aibă loc Această

conexiune nu este efectiv una fizică ci virtuală asemănător cum se icircntacircmplă icircn sistemul de

telefonie clasică cineva formează un număr şi abia icircn momentul icircn care cealaltă persoană

răspunde se poate icircncepe conversaţia Fiind o conexiune host-la-host nu există noţiunile de

broadcast sau multicast

Transferul sigur de date este asigurat icircn următorul mod

Datele sunt icircmpărţite icircn bucăţi a căror dimensiune optimă e determinată de TCP spre

deosebire de UDP care trimite datagrame UDP corespunzătoare cu dimensiunea datelor

primite de la nivelul aplicaţie Unitatea de date trimisă de TCP către nivelul reţea poartă

numele de segment

Cacircnd TCP trimite un segment porneşte un timer şi dacă nu se primeşte confirmarea

segmentului respectiv icircntr-un anumit timp icircl retransmite

Icircn momentul icircn care se primeşte un segment TCP trimite o confirmare (din motive de

eficienţă aceasta poate fi amacircnată un anumit interval de timp)

Icircn headerul TCP este menţinută o sumă de control pentru detectarea modificărilor icircn date

Dacă se recepţionează un segment corupt TCP icircl ignoră urmacircnd să fie retransmis datorită

neprimirii confirmării

Deoarece segmentele TCP sunt transmise mai departe icircncapsulate icircn datagrame IP iar

acestea pot ajunge icircn orice ordine segmentele TCP pot ajunge icircn altă ordine decacirct cea icircn

care au fost trimise De aceea la destinaţie TCP-ul trebuie să se folosească de numere de

secvenţă pentru a reordona eventual segmentele icircnainte de a le livra către nivelul

aplicaţie De asemenea TCP trebuie să asigure ignorarea duplicatelor

TCP asigură controlul fluxului icircn condiţiile icircn care viteza de trimitere a datelor de la sursă

poate fi mult prea mare decacirct capacitatea de prelucrare de la destinaţie

Serviciul oferit de TCP este de tip flux de octeţi deoarece oferă garanţii că fluxul de date trimis

de sursă va fi livrat fără modificări la destinaţie Comparativ UDP-ul produce pentru fiecare

transfer cerut de nivelul aplicaţie un pachet IP (care ulterior poate fi supus fragmentării) care

dacă ajunge la destinaţie corect va fi livrat direct nivelului aplicaţie fără a garanta icircn vreun fel

ordinea

2 Formatul pachetelor TCP

Pachetele de date transmise de TCP segmentele sunt formate dintr-un antet (figura 72) de 20

octeţi urmat de datele primite de la nivelul aplicaţie Antetul poate uneori conţine şi o serie de

opţiuni caz icircn care poate ajunge la 60 octeţi

Figura 72 Structura unui segment TCP

Antetul unui segment TCP cuprinde

port sursă - 16 biţi pentru specificarea portului aplicaţiei transmiţătoare

port destinaţie - 16 biţi pentru specificarea portului aplicaţiei ce recepţionează segmentul

TCP

Aceste două porturi icircmpreună cu adresele ale sursei şi destinaţiei conţinute icircn antet-ul IP

identifică icircn mod unic conexiunea Pentru o pereche formată dintr-o adresă IP şi un port

se foloseşte adesea denumirea de socket (denumire introdusă icircn specificaţiile iniţiale ale

protocolului TCP icircn RFC 793)

număr de secvenţă - 32 biţi

Pentru a asigura un serviciu de tip flux de octeţi TCP numerotează fiecare octet de date

utilizacircnd un număr de secvenţă Numărul de secvenţă din cadrul antetului TCP specifică

destinaţiei care este primul octet din fluxul trimis La iniţierea unei conexiuni se setează

flag-ul SYN şi se alege aleator un număr de secvenţă de icircnceput utilizacircnd un generator de

numere de secvenţă ISN (Initial sequence number) Numărul de secvenţă al primului

octet de date va fi numărul generat ISN plus 1 deoarece pachetul de iniţiere (cu SYN

setat) consumă şi el un număr de secvenţă Se va vedea mai departe că şi flag-ul de

terminare a conexiunii FIN consumă şi el un număr de secvenţă

confirmare - 32 biţi

Reprezintă numărul de secvenţă al octetului de date pe care transmiţătorul confirmării se

aşteaptă să-l primească Astfel dacă s-a recepţionat octetul cu numărul de secvenţă x (icircn

numerotaţia sursei) pachetul de confirmare va avea flag-ul ACK setat şi va conţine

numărul de confirmare x + 1 Trimiterea unui ACK nu consumă un număr de secvenţă

deoarece atacirct acest cacircmp cacirct şi flag-ul ACK fac parte din antet şi după stabilirea

conexiunii ambele cacircmpuri devin active Acest mecanism nu permite confirmări selective

pentru că numărul de secvenţă specifică pacircnă unde s-au recepţionat date De exemplu

dacă la destinaţie au ajuns octeţii 1-1024 şi următorul segment primit conţine octeţii

2049-3072 nu se poate trimite confirmare pentru cel de-al doilea segment deci

confirmarea va cuprinde numărul de secvenţă 1025

lungimea antetului - 4 biţi

Specifică dimensiunea antetului ca număr de cuvinte de 32 de biţi (4 octeţi) Antetul

poate avea icircntre 20 şi 60 de octeţi deci valoarea acestui cacircmp va fi icircntre 5 (5 x 4 = 20

octeţi) şi 15 (15 x 4 = 60)

6 biţi rezervaţi pentru utilizări viitoare

6 biţi de control reprezentacircnd următoarele flag-uri ce pot fi setate simultan

o URG - cacircmpul urgent pointer este valid

o ACK - cacircmpul de confirmare este valid

o PSH - destinaţia trebuie să trimită datele către nivelul aplicaţie cacirct mai devreme

o RST - se doreşte resetarea conexiunii

o SYN - iniţierea conexiunii

o FIN - icircnchiderea conexiunii

dimensiunea ferestrei - 16 biţi

Reprezintă numărul de octeţi (icircncepacircnd cu numărul de secvenţă conţinut icircn cacircmpul de

confirmare) pe care destinaţia e dispusă să-l primească Este limitat la 65535 octeţi dar

cu toate că pare o limită destul de mare există situaţii cacircnd se doresc valori mult mai

mari Icircn acest scop se folosesc nişte opţiuni speciale descrise ceva mai tacircrziu care permit

scalarea ferestrei

suma de control - 16 biţi

Această sumă de control acoperă icircntregul segment TCP (atacirct datele cacirct şi antetul TCP) şi

spre deosebire de UDP este obligatoriu să fie completat de transmiţător şi verificat de

receptor Dar ca şi icircn cazul UDP-ului la calculul sumei de control se ia in considerare şi

o zona specială de 12 octeţi ce cuprinde pentru re-verificare cacircmpuri din antetul IP

(adresa IP a sursei şi a destinaţiei)[aici tre sa vina o referire la poza cu pseudo-antetu]

După adăugarea acestui pseudo-antet datele se icircmpart icircn cuvinte de 16 biţi icircn vederea

calculării sumei de control adăugacircndu-se eventual şi un octet de aliniere

urgent pointer - 16 biţi

Este utilizat pentru specificarea deplasamentului ultimului octet de date trimis icircn regim

urgent Astfel ultimul octet din secvenţa urgentă se obţine adunacircnd acest cacircmp la

numărul de secvenţă Ce icircnseamnă acest mod urgent de transmitere există situaţii icircn care

aplicaţiile vor să trimită date `neordonate` Să presupunem că aplicaţia a trimis către

nivelul transport o cantitate mare de date dar la un moment dat observă ceva icircn neregulă

şi doreşte să anuleze operaţia Dacă trimite o comandă de anulare aceasta va fi adăugată

la sfacircrşitul şirului de octeţi deci nu se va putea icircmpiedica ajungerea acestora la nivelul

aplicaţie de la receptor Activacircnd modul urgent datele urgente (comanda de anulare) vor

fi plasate la icircnceputul pachetului Aplicaţiile mai cunoscute care folosesc acest mod sunt

Telnet Rlogin şi FTP

opţiuni - pacircnă la 40 de octeţi (figura 73)

Cele mai utilizate opţiuni sunt

o Sfacircrşit de opţiuni (end of option) - 1 octet

Este utilizat pentru alinierea datelor conţinute icircn cacircmpul de opţiuni Nu poate fi

utilizat decacirct o singură dată marcacircndu-se astfel sfacircrşitul opţiunilor şi icircnceperea

datelor efective Dacă pentru alinierea la un cuvacircnt de 32 de biţi e nevoie de mai

mult de 1 byte se va utiliza opţiunea no operation Orice apare după această

opţiune pacircnă la icircnceputul cuvacircntului următor de 32 de biţi e ignorat

o no operation - 1 octet

Utilizat pentru alinierea la cuvinte de 32 de biţi

o Dimensiunea maximă a segmentului (Maximum Segment Size (MSS)) - 16 biţi

Icircn ciuda denumirii defineşte lungimea maximă a datelor nu dimensiunea

icircntregului segment Poate lua valori icircntre 0 şi 65535 valoarea implicită fiind 536

Această opţiune e valabilă doar icircn pachetele de iniţiere a conexiunii (cele cu flag-

ul SYN setat) fiecare parte făcacircnd cunoscută dimensiunea maximă a datelor

dispusă să le primească icircntr-un pachet Icircn principiu cu cacirct această valoarea e mai

mare e mai bine (deoarece se recuperează din spaţiul ocupat de antetele TCP şi

IP) pacircnă cacircnd apare fragmentarea Valoarea maximă la care se poate seta este

MTU (Maximum Transfer Unit) minus dimensiunea antetului IP şi TCP (1460

octeţi icircn cazul Ethernet)

o Factor de scalare a ferestrei (Window scale factor) - 1 octet

Pentru situaţiile icircn care se doreşte utilizarea unei ferestre mai mare de 65535 bytes

se poate utiliza acest cacircmp pentru mărirea dimensiunii ferestrei Noua dimensiune

va fi Chiar dacă

factorul de scalare poate fi maxim 255 icircn cazul TCPIP el nu poate depăşi

valoarea 16 deoarece dimensiunea maximă a ferestrei nu poate fi mai mare decacirct

valoarea celui mai mare număr de secvenţă ( )

Acest factor se poate seta doar la iniţierea conexiunii Icircn timpul transferului de

date se poate modifica dimensiunea ferestrei dar factorul de scalare rămacircne

acelaşi Dacă cel care a iniţiat conexiunea a trimis icircn segmentul de iniţiere şi acest

factor dar icircn pachetul cu ACK destinatarul nu şi-a trimis şi el factorul atunci se la

considera 0 icircn ambele direcţii Invers dacă cel care solicită deschiderea

conexiunii nu setează factorul destinaţia nu va putea seta factorul de scalare

o Timestamp - 10 octeţi

Utilizat pentru reţinerea timpului icircn vederea calculării RTT (Round Trip Time)

Cacircmpul timestamp e completat de sursă icircn momentul trimiterii segmentului La

destinaţie valoarea este reţinută şi copiată icircn cacircmpul timestamp echo reply al

pachetului cu confirmarea RTT-ul este calculat de sursă făcacircnd diferenţa dintre

timpul curent şi această valoare

Figura Opţiuni TCP

3 Iniţierea şi terminarea unei conexiuni TCP

TCP este un protocol orientat conexiune deci presupune stabilirea unei căi virtuale icircntre sursă şi

destinaţie

Subsections

Protocolul de iniţiere

o 1 Deschiderea simultană

Protocolul de terminare

o 2 Terminarea simultană

o 3 Resetarea conexiunii

Diagrama de stări

Protocolul de iniţiere

Modul de transmisie icircn cazul protocolului TCP este full-duplex deci sunt transmise date

simultan icircn ambele direcţii Aceasta presupune că cel care iniţiază conexiunea trebuie să

primească aprobarea celuilalt capăt icircnainte de icircnceperea transferului de date sursa icircşi anunţă

intenţia de a iniţia o conexiune destinaţia trimite un pachet cu confirmarea cererii şi un pachet de

iniţiere a conexiunii de la el la sursă iar apoi sursa confirmă cererea primită de la destinaţie Paşii

2 şi 3 pot fi realizaţi prin trimiterea unui singur pachet de aceea protocolul de iniţiere este

cunoscut sub numele de three-way handshake

Icircn cadrul protocolului de iniţiere există 2 tipuri de cereri de iniţiere cerere activă (active open)

iniţiată de clientul ce doreşte să stabilească conexiunea cu serverul şi cerere pasivă (passive

open) din partea serverului

Cei 3 paşi sunt

1 Clientul trimite un segment cu flag-ul SYN setat şi care conţine portul sursă portul de la

destinaţie şi numărul de secvenţă generat iniţial (ISN) de la care se vor numerota octeţii

de la client către server Opţional se pot stabili parametrii conexiunii prin setarea lungimii

maxime a segmentelor (MSS) dispus să le primească de la server factorului de scalare a

ferestrei Acest prim segment nu conţine nici un parametru de confirmare şi de asemenea

nu are rost să conţine să seteze dimensiunea ferestrei

2 Al doilea segment e trimis de server şi are un rol dublu confirmă segmentul primit de la

client prin setarea flag-ului ACK şi completează numărul de secvenţă cu numărul de

secvenţă primit plus 1 şi al doilea rol iniţializează conexiunea de la el către client prin

setarea flag-ului SYN şi generarea unui număr de secvenţă iniţial ce va fi folosit icircn

numerotarea octeţilor de la server spre client Pe lacircngă aceasta trebuie să conţină

dimensiunea ferestrei şi opţional poate seta factorul de scalare şi dimensiunea maximă a

segmentului acceptat

3 Clientul trimite un segment cu confirmarea cererii din partea serverului (ACK setat +

completează numărul confirmat cu numărul de secvenţa primit + 1) Ca şi icircn cazul

pasului 2 trebuie să seteze dimensiunea ferestrei Acest pachet poate conţine date

Subsections

1 Deschiderea simultană

1 Deschiderea simultană

Se poate icircntacircmpla ca uneori cele două capete care vor să comunice să icircncerce să stabilească

conexiunea simultan Icircn acest caz după ce fiecare a trimis segmentul de iniţiere (iniţiere activă)

ambele vor trimite un segment cu SYN + ACK şi se va stabili o singură conexiune nu două

Protocolul de terminare

Oricare dintre cele două părţi poate solicita icircnchiderea conexiunii dar conexiunea fiind full-

duplex transferul de date icircn celălalt sens poate continua (această situaţie e denumită half-close)

O icircnchidere completă a unei conexiuni TCP presupune următorii paşi

1 Clientul trimite un segment cu flag-ul FIN activat solicitacircnd icircnchiderea conexiunii

2 Serverul trimite un segment ACK confirmacircnd primirea cererea Numărul de confirmare

se completează normal ca numărul de secvenţă primit + 1

3 Serverul continuă să trimită date către client şi cacircnd doreşte să icircnchidă şi el conexiunea

trimite un segment cu FIN activat

4 Clientul trimite un pachet ACK confirmacircnd icircnchiderea conexiunii

Cel care iniţiază primul procedura de icircnchidere (trimite primul FIN) realizează o icircnchidere activă

(active close) iar celălalt capăt o icircnchidere pasivă (passive close) Icircn mod normal cel care

realizează iniţierea activă va fi primul ce va trimite FIN dar oricare dintre cei doi poate icircnchide

activ conexiunea

Subsections

2 Terminarea simultană

3 Resetarea conexiunii

2 Terminarea simultană

Icircn mod similar cu deschiderea simultană există posibilitatea ca ambele capete ale conexiunii TCP

să iniţieze simultan procedura de icircnchidere a conexiunii Icircn acest caz ambele părţi vor trimite

FIN şi vor aştepta primirea unui ACK Icircn continuare fiecare va primi cererea de terminare şi va

trimite ACK Se observă că numărul de segmente transferate pentru realizarea icircnchiderii

conexiunii (4 segmente) este acelaşi ca la terminarea normală

3 Resetarea conexiunii

Există situaţii icircn care TCP doreşte resetarea conexiunii De exemplu dacă se solicită iniţierea

unei conexiuni la un port inexistent Icircn acest caz cealaltă parte va trimite un segment cu bitul

RST setat pentru a anula solicitarea O altă situaţie este atunci cacircnd se constată că celalalt capăt

al conexiunii nu răspunde un anumit timp (timeout)

Diagrama de stări

Toate evenimentele ce au loc icircn timpul stabilirii conexiunii transferului şi icircnchiderii conexiunii

pot fi rezumate printr-un automat finit cunoscut sub numele de diagrama de stări După cum

chiar numele sugerează este o maşină cu un număr limitat de stări O stare este păstrată pacircnă icircn

momentul apariţiei unui eveniment moment icircn care se poate trece icircn altă stare şisau efectua o

acţiune

Aceste stări posibile sunt (denumirile sunt asemănătoare cu cele utilizate de netstat) cele din

tabelul 71

Tabela Stările diagramei de stări TCP

Stare Descriere

CLOSED Nu există conexiune

LISTEN Serverul aşteaptă cereri de la clienţi

SYN_SENT Cerere de iniţiere (activă) a conexiunii Se

aşteaptă confirmarea

SYN_RCVD S-a primit o cerere de iniţiere conexiune

ESTABLISHED S-a stabilit conexiunea

FIN_WAIT_1 Aplicaţia a solicitat icircnchiderea conexiunii

FIN_WAIT_2 Serverul a acceptat icircnchiderea conexiunii

CLOSING Ambele părţi solicită simultan icircnchiderea

conexiunii

TIME_WAIT Conexiune icircnchisă dar se aşteaptă ca

pachetele retransmise să dispară

CLOSE_WAIT Serverul aşteaptă icircnchiderea dinspre partea

aplicaţiei

LAST_ACK Serverul a icircnchis conexiunea Aşteaptă

ultima confirmare

Icircn diagrama ilustrată icircn figura 74 putem observa 3 tipuri de tranziţii icircntre cele 11 stări tranziţii

ce corespund unei funcţionări normale pentru client (linii normale continue) pentru server (linii

normale icircntrerupte) şi tranziţii pentru situaţii nestandard (linii subţiri continue)

O comportarea normală pentru client presupune parcurgerea următoarelor stări CLOSED

SYN_SEND ESTABLISHED FIN_WAY_1 FIN_WAY_2 TIME_WAIT

Iniţial clientul TCP se află icircn starea CLOSED

Aşteptacircnd icircn starea CLOSED clientul poate primi de la aplicaţie o cerere de iniţiere

activă a unei conexiuni Trimite un segment SYN şi trece icircn starea SYN_SENT

Icircn starea SYN_SENT clientul aşteaptă de la server un segment ACK+SYN după care

trimite un ACK şi trece icircn starea ESTABLISHED Din acest moment poate icircncepe

transferul efectiv de date Clientul va rămacircne icircn această stare cacirct timp are de trimisprimit

date

Aflat icircn această stare clientul TCP poate primi din partea aplicaţiei o cerere de icircnchidere a

conexiunii Icircn acest caz va trimit un segment FIN şi trece icircn starea FIN_WAIT_1

Icircn această stare clientul aşteaptă ACK din partea serverului După ce-l primeşte

conexiunea icircntr-un sens se va icircnchide şi clientul trece icircn starea FIN_WAIT_2

Starea FIN_WAIT_2 durează pacircnă cacircnd primeşte cererea de icircnchidere a conexiunii FIN

din partea serverului Trimite ACK şi va trece icircn starea TIME_WAIT

Icircn această stare se va porni un timer cu valoarea setată la dublul timpului de viaţă estimat

pentru un segment de lungime maximă MSL (Maximum Segment Lifetime) Acest timer

permite retransmiterea ACK-ului icircn cazul icircn care acesta se pierde (celălalt capăt va da

timeout şi va retransmite segmentul FIN) Icircn tot acest time cei doi sockeţi (de la client şi

server) nu vor putea fi reutilizaţi Totodată pachetele icircntacircrziate care sosesc icircn această

perioadă sunt ignorate După expirarea acestui timer clientul revine icircn starea iniţială

CLOSED

Din punctul de vedere al unui server o comportare standard parcurge următoarele stări

CLOSED LISTEN SYN_RCVD ESTABLISHED CLOSE_WAIT şi LAST_ACK

Iniţial serverul TCP se află icircn starea CLOSED

Icircn această stare poate primi de la aplicaţia server o cerere de iniţiere activă şi trece icircn

starea LISTEN

Aflat icircn starea LISTEN serverului TCP poate recepţiona un segment SYN de la un client

TCP Icircn acest caz va trimite ACK+SYN şi va trece icircn starea SYN_RCVD

Icircn această stare serverul aşteaptă primirea confirmării de la client moment icircn care

conexiunea e stabilită icircn ambele sensuri şi se poate icircncepe transferul de date (starea

ESTABLISHED)

Clientul TCP poate solicita icircnchiderea conexiunii trimiţacircnd un segment FIN către server

Icircn acest caz serverul TCP trimite confirmarea şi trece icircn starea CLOSE_WAIT

Icircn această stare serverul aşteaptă să primească din partea programului server icircnchiderea

conexiunii moment icircn care va trimite către client un segment FIN şi trece icircn starea

LAST_ACK

Serverul aşteaptă primirea ultimei confirmări de la client după care revine icircn starea

CLOSED

Atacirct serverul cacirct şi clientul TCP se pot afla icircn oricare din cele 11 stări ale diagramei

Figura Diagrama de stări pentru TCP

4 Controlul fluxului

Dacă icircncă de la icircnceput s-a reuşit stabilirea formatului unui pachet TCP şi a modulului icircn care

trebuie să se facă icircnchiderea şi deschiderea unei conexiuni nu acelaşi lucru se poate spune şi

despre modul icircn care ar trebui să se realizeze controlul fluxului Ţinacircnd seama icircnsă că din 1989

(de cacircnd datează RFC-ul 2581 cel despre care am menţionat că specifică icircn mod clar modul icircn

care trebuie să se comporte o implementare de TCP) TCP-ul a rămas neschimbat putem să icircl

considerăm un rezultat important al domeniului reţelor de calculatoare

Icircn cele ce urmează vom icircnţelege prin controlul fluxului totalitatea algoritmilor care permit

atingerea unei viteze de transfer punct-la-punct cacirct mai mare pentru toate conexiunile existente

Icircn principal aceşti algoritmi stabilesc modul icircn care segmentele şi confirmările trebuie trimise şi

ce acţiuni trebuie executate icircn situaţiile icircn care răspunsurile aşteptate de la celălalt capăt icircntacircrzie

să vină

Subsections

Icircntacircrzierea confirmărilor

Algoritmul Nagle

Fereastra glisantă

Slow start

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Evitarea congestiei

Fast Retransmission Fast Recovery

Sindromul ``Silly Window

TCP Keepalive Timer

Icircntacircrzierea confirmărilor

O modalitate simplă de generare a confirmărilor este de a trimite cacircte una pentru fiecare segment

primit Această politică prezintă avantajul de a face comunicaţia self-clocking icircnsă este

ineficientă dacă segmentele care nu conţin decacirct confirmări sunt urmate la scurtă distanţă (cacircteva

zeci de milisecunde) de segmente ce conţin date efective Pentru a evita această situaţie se

procedează2 la icircntacircrzierea (200ms este o valoare uzuală icircn RFC 1122 se specifică o valoare

maximă de 500ms) a segmentelor care conţin doar confirmări Această strategie face posibil ca

un răspuns generat de primirea unor date să plece sper celălalt capăt icircn acelaşi segment cu

confirmarea

Observaţie deoarece este dificil de menţinut timere pentru fiecare confirmare diferenţa de

200ms este calculată de un timer global Din acest motiv modul efectiv de comportare poate fi

descris şi icircn felul următor cacircnd un segment nu conţine decacirct o confirmare el este pus icircntr-o

coadă ce va fi inspectată de un proces care din 200 icircn 200 ms trimite tot ce s-a acumulat icircn

coada

Footnotes

2

Acest comportament a fost propus de David D Clark icircn iulie 1982 icircn RFC 813

Algoritmul Nagle

Acest algoritm3 icircncearcă să icircmbunătăţească performanţele exploatacircnd următoarea caracteristică

foarte des icircntacirclnită icircn dialogul dintre două staţii dacă se icircncearcă trimiterea unor date de

dimensiune mică icircnsă există icircncă date neconfirmate de partener atunci ele sunt buffer-ate şi

trimise icircntr-un segment mai mare cacircnd soseşte confirmarea aşteptată Icircn acest fel se poate evita

generarea datagramelor mici (tinygrame) icircn situaţia unei legături lente Icircn cazul unei legături

rapide confirmările vor veni repede şi icircntacircrzierea introdusă de algoritm va neglijabilă

Există icircnsă şi cazuri icircn care acest algoritm duce la deprecierea performanţelor mesajele scurte

generate de mişcările mouse-ului icircn cazul folosirii unui server X Window sau utilizarea tastelor

care trimit mai mult de un caracter (secvenţe escape) Pentru a rezolva aceste inconveninte API-

ul de utilizare a TCP-ului trebuie să ofere o modalitate de a dezactiva acest algoritm (icircn sistemele

bazate pe sockeţi există icircn acest scop opţiunea TCP_NODELAY)

Footnotes

algoritm3

Algoritmul aparţinacircnd lui John Nagle a fost propus icircn ianuarie 1984 icircn RFC 896

Fereastra glisantă

Algoritmul implementat de TCP pentru a implementa transferul sigur de date este cunoscut icircn

teorie sub numele de Go-Back-N Icircn acest algoritm se utilizează numere de secvenţă pentru a

distinge pachetele icircntre ele şi o coadă (dimensiunea maximă a cozii reprezintă fereastra) de

pachetele a căror confirmare se aşteaptă Pachetele se icircmpart icircn 4 categorii

1 pachete trimis şi pentru care s-a primit confirmare

2 pachete trimise şi pentru care se aşteaptă icircncă confirmarea

3 pachete care nu au fost trimise icircncă dar care nu depăşesc limitele ferestrei şi deci pot fi

trimise

4 pachete care icircncă nu au fost trimite şi care nici nu vor putea fi trimise decacirct după ce au

fost trimise toate pachetele din categoria 3 şi s-au primit o parte din confirmările la

pachetele din categoria 2

Dacă confirmările pentru pachetele din categoria 2 icircntacircrzie prea mult (un mecanism de timer-e

informează asupra acestui lucru) atunci ele vor fi retrimise Icircn versiunea iniţială TCP-ul nu

permitea decacirct confirmări pozitive ceea ce icircnseamnă că avansarea ferestrei se va icircmpotmoli la

segmentele neconfirmate Cum se poate evita aceasta situaţie vom discuta icircn detaliu icircn capitolele

următoare O soluţie foarte radicală o constituie introducerea de confirmări selective (acest lucru

este realizat de RFC 2018 din octombrie 1996) Această modifică face ca TCP-ul actual să fie un

hibrid de Go-Back-N şi Selective Repeat

Deoarece dimensiunea ferestrei este anunţată la fiecare segment un client lent poate ca pe măsură

ce trimite confirmările să informeze despre progresul icircnregistrat la livrarea datelor următorului

nivel (aplicaţie) Dacă datele vin prea repede pentru viteza cu care clientul procesează datele

fereastra fereastra se va dimiua şi chiar icircnchide (acest lucru se realizează anunţacircnd o fereastră de

dimensiune zero) Cum se realizează efectiv redeschiderea vom analiza icircntr-un capitol viitor

Slow start

Un transfer de date TCP poate să icircnceapă prin transmiterea de segmente pacircnă la umplerea

icircntregii ferestre după care fie se primesc confirmări care vor permite unor noi pachete să fie

trimise fie vor expira timer-ele de retransmisie şi se va icircncepe retrimiterea pachetelor de la

icircnceputul ferestrei Din păcate un astfel de comportament poate duce la pomparea icircn reţea a unui

număr de pachete prea mare pentru capacitatea disponibilă efectiv icircnrăutăţind congestia Pentru

a evita acest lucru s-a propus următoarea soluţie4 iniţial se trimite un segment după primirea

confirmării lui se trimit două segmente după sosirea confirmărilor pentru ele se trimit patru

segmente şi aşa mai departe La un moment dat fie vor icircncepe să se piardă segmente (un indiciu

că s-a atins capacitatea maximă a canalului) fie se va umple fereastra pe care o anunţă cel care

primeşte Trebuie să remarcam că datorită creşterii exponenţiale a numărului de segmente se va

atinge destul de repede una din cele două situaţii

Modalitatea efectivă de implementare a acestui algoritm are la bază utilizarea unei ferestre de

congestie (congestion window cwnd) care este iniţializată cu dimensiunea unui segment (cwnd

se calculează icircn octeţi) şi la fiecare pas este dublată fereastra efectivă din cadrul căreia se pot

trimite segmente este dată de minimul dintre ultima fereastra comunicată de partener şi cwnd

Footnotes

soluţie4

Soluţia aparţine lui V Jacobson şi a fost prezentată icircn 1988 la conferinţă ACM

SIGCOMM-88

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Deoarece TCP trebuie să funcţioneze icircn condiţii variate de latenţă modul icircn care se face

retransmiterea trebuie să fie cacirct mai flexibil (şi simplu icircn acelaşi timp pentru a introduce un

overhead cacirct mai mic) Timpul cacirct se aşteaptă venirea unei confirmări (retransmission timeout

RTO) este calculat prin cronometrarea timpului care icirci ia unui segment trimis să fie confirmat

Pentru o anumită conexiune se cronometrează cacircte un singur segment la un moment dat iar pe

baza RTT-ului măsurat se actualizează valoare RTO-ului

Icircn RFC 793 formula de calcul a RTO-ului este următoarea

unde este ultimul RTT măsurat este o estimare ponderată pentru RTT este un coeficient

de ponderare care icircn general are valoarea iar este un coeficient cu o valoare recomandată

de După cum se poate observa icircn valoarea lui este inclusă icircn mare măsură vechea valoarea

Icircn acest fel ajustarea RTT-ului se face treptat Din păcate acest mod de calcul nu funcţionează

bine la variaţii mari ale RTT-ului ducacircnd la creşterea numărului de retransmisii exact atunci

cacircnd fenomenul de congestie icircncepe să apară

Pentru a remedia aceste neajunsuri V Jacobsen a propus icircn 1988 o nouă metodă de calcul o

metodă care ţine seama seamă şi de modul icircn care variază diferenţa dintre RTT-uri Formulele

folosite sunt următoarele

unde este un estimare pentru media RTT-urilor este o estimare pentru abaterea RTT-urilor

faţă de medie (o aproximaţie suficientă pentru abaterea pătratică medie care icircnsă este mult mai

costisitor de calculat) este diferenţa dintre RTT-ul măsurat ( ) şi estimarea curentă ( )

Coeficientul cu care este actualizată estimarea curentă are valoarea de iar cel cu care este

actualizat estimarea abaterii este La stabilirea unei conexiuni valorile pentru şi sunt

alese astfel icircncacirct să rezulte un RTT de secunde şi un de 3 secunde (aceste recomandări

sunt făcute de RFC 1122)

Dacă pentru un anumit segment nu se primeşte confirmarea icircn intervalul indicat de el va fi

retrimis şi noul este dublat Valoarea maximă admisă pentru este de 240 secunde

Deoarece icircn cazul retrimiterilor nu se poate determina cu exactitate căruia din segmentele trimise

aparţine confirmarea actualizarea estimărilor este amacircnată pacircnă cacircnd se reuşeşte trimiterea

corectă (s-a primit confirmare) fără retransmitere(``din prima) a unui segment Acest artificiu

(deloc neimportant) care permite evitarea actualizarea eronată a estimărilor este cunoscut sub

numele de algoritmul lui Karn şi a fost propus icircn 1987 de P Karn şi C Partridge

Evitarea congestiei

Dacă cei doi parteneri care comunică prelucrează datele suficient de repede şi vor să transfere un

volum mare de date atunci limitarea de care se vor lovi este cea dată de viteza reţelei Din cauza

modului ``best-effort pe care IP-ul icircl oferă cacircnd canalul de comunicaţie este saturat o parte din

segmentele TCP se vor pierde Icircn mod poate paradoxal atacirct transmiţătorului cacirct şi receptorul se

pot afla icircn poziţia de a fi primii icircn detectarea pierderii unui segment Unul din indiciile de la

transmiţător care semnalează pierderea unui segment este (icircn mod evident) apariţia 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 icircn varianta iniţială nu

permite decacirct confirmări pozitive singurul lucru pe care receptorul icircl poate face este ca la fiecare

segment out-of-order primit să trimită o confirmare indicacircnd prin aceasta că la el continuă să

vină segmente icircnsă cel indicat de numărul de secvenţă de confirmare lipseşte Primirea acestor

confirmări multiple este al doilea mod icircn care transmiţătorul poate afla de apariţia congestiei

Algoritmul ce trebuie aplicat icircn momentul icircn care se detectează apariţia congestiei este cunoscut

sub numele de ``evitarea congestiei (congestion avoidence) Principiul care stă la baza lui este

ca la apariţia congestiei fie să se treacă la o incrementare liniară a dimensiunii ferestrei dacă

congestia a fost detectată ca urmare a primirii unor confirmări identice repetate fie să se reia

slow start-ul icircn cazul icircn care congestia s-a detectat prin expirarea unui timer de timeout

Implementarea acestui algoritm se bazează pe utilizarea unui nou contor (sstresh) care să indice

dimensiunea ferestrei de la care se trece de la incrementarea exponenţială la cea liniară

Algoritmul efectiv este următorul

1 la stabilirea unei noi conexiuni se pleacă cu sstresh iniţializat la valoare de 64K şi cwnd

la dimensiunea unui segment

2 trimiterea de segmente se face fără a depăşi minimul dintre fereastra publicată de partener

(pentru a nu depăşi capacitatea de procesesare a partenerului) şi cwnd-ul curent (pentru a

nu depăşi limita impusă de capacitatea reţelei)

3 la apariţia congestiei sstresh este setat la jumătatea valorii ferestrei curente (minimul

dintre fereastra anunţată de partener şi cwnd icircnsă cel puţin dimensiunea corespunzătoare

pentru două segmente) dacă congestia a fost detectată prin expirarea unui timer de

timeout atunci cwnd este iniţializat cu dimensiunea unui segment

4 la primirea unei confirmări incrementarea se face icircn două moduri icircn funcţie de relaţie icircn

care se află cwnd şi sstresh

1 dacă cwnd e mai mic sau egal cu sstresh se face incrementarea exponenţială

caracteristică slow start-ului (care de fapt nu e deloc slow icircn cazul de faţă)

2 dacă cwnd e mai mare ca sstresh atunci se face o incrementare cu dimensiunea

unui segment

Fast Retransmission Fast Recovery

După cum am văzut un receptor care primeşte segmente out-of-order va trimite transmiţătorului

confirmări duplicate Algoritmul denumit ``fast retransmission recomandă următoarele două

comportamenet

1 un receptor care detectează segmente out-of order trebuie să nu icircntacircrzie trimiterea de

confirmări (după cum am văzut icircn general confimările sunt icircntacircrziate micşora numărul de

pachete fără date care sunt transferate)

2 un transmiţător care care primeşte mai mult de trei confirmări duplicate trebuie să

retrimită segmentul indicat ca fiind neprimit de confirmările icircn cauză fără a aştepta

expirarea timer-ul de timeout

Algoritmul de ``fast recovery icircncearcă să optimizeze şi mai mult comportamentul

transmiţătorului care detectează un număr de trei sau mai multe confimări duplicate Mai exact el

recomandă trecerea la actualizarea liniară a ferestrei (congestion avoidance) Acest tip de

comportament se poate justifica prin următorul raţionament deoarece icircncă mai sunt transferate

date icircntre cei doi parteneri (şi acest lucru se icircntacircmplă sigur de vreme ce sosesc confirmări

duplicate icircn cazul acesta) icircnseamnă că transferul nu este afectat de o congestie severă şi prin

urmare trecerea la slow start nu e (icircncă) necesară (slow start-ul eliberează aproape complet

canalul deoarece cwnd este resetat la dimensiunea unui singur segment)

Cei doi algoritmi pot fi implementaţi icircn felul următor

1 cacircnd se detectează trei confirmări consecutive identice se setează sstresh la jumătate din

valoarea cwnd se retransmite segmentul care s-a pierdut şi se setează cwnd la valoarea

egală cu sstresh plus dimensiunea a trei segmente (acest lucru va face ca algoritmul de

incrementare a cwnd să treacă la incrementare liniară)

2 la fiecare confirmare duplicată care mai soseşte se incrementează cwnd se incrementează

cu dimensiunea unui segment

3 cacircnd icircncetează primirea de confirmări duplicate (segmentul retrimis a ajuns cu bine la

receptor şi s-a trimis o confirmare care acoperă segmentul care se pierduse iniţial) cwnd

este setat la valoarea sstresh

Sindromul ``Silly Window

Protocoalele bazate pe fereastră glisantă (cum este şi TCP-ul) pot să ajungă icircn situaţia deloc

fericită de trimite un număr mare de segmente mici icircn loc de segmente de dimensiune maximă

Acest tip de comportament este cunoscut sub numele de sindromul ``silly window

O modalitate prin care TCP-ul poate să cadă victimă acestui tip de comportament este

deschiderea de ferestre cu dimensiune foarte mică O altă situaţia nefericită este cea icircn care un

transmiţător este ``lacom şi trimite date indiferent de cacirct de mică este fereastra (după cum vom

vedea imediat uneori are sens şi un astfel de comportament) Algoritmul de evitare a acestor

neajunsuri este următorul

1 un receptor nu trebuie să anunţe deschideri de ferestre mici Mai exact nu se recomandă

anunţarea unei incrementări a ferestrei mai mică decacirct dimensiunea unui segment (MSS)

sau jumătate din buffer-ul aflat la dispoziţia receptorului oricare din ele e mai mică

2 un transmiţător va trimite date doar icircn următoarele cazuri

1 se poate trimite un segment icircntreg

2 se poate trimite jumătate din dimensiunea celei mai mari ferestre pe care

partenerul a publicat-o pacircnă acum

3 toate datele trimise pacircnă acum au fost confirmate sau algoritmul Nagle este

dezactivat şi se trimit toate datele care sunt icircn buffer-ul de trimitere

Cacircteva justificări cazul 2b tratează cazul icircn care partenerul anunţă ferestre mai mici decacirct

dimensiunea unui segment iar cazul 2c impune condiţiile respectării algoritmului Nagle după

cum se vede dacă algoritmul Nagle este activ şi s-au acumulat destul date mai exact cacirct

dimensiunea unui segment el va fi trimis chiar dacă există segmente neconfirmate Pentru

implementarea comportamentului impus de 2b un transmiţător trebuie să ţină evidenţa celei mai

mari ferestre pe care partenerul a anunţat-o Ţinacircnd seama că dimensiunea acestor buffer-e nu se

modifică acest mod de a icircncerca determinarea lor este suficient

O altă problemă legată tot de ferestre este cazul icircnchiderii acesteia Un mod icircn care s-ar putea

anunţa redeschiderea este trimiterea de către receptor a unei confirmări (duplicat) care să anunţe

redeschiderea la o anumită valoare a ferestrei Deoarece acest pachet nu trebuie confirmat icircn mod

special şi s-ar putea să se piardă se poate ajunge icircn situaţia icircn care receptorul a anunţat

redeschiderea ferestrei segmentul s-a pierdut iar transmiţătorul icircncă mai icircl mai aşteaptă pentru a

putea continua transferul Rezolvarea la această problemă s-a făcut prin impunerea unui alt

comportament

1 transmiţătorul va trimite segmente cu dimensiunea datelor de un octet prin care sondează

deschiderea ferestrei intervalul la care se sondează redeschiderea ferestrei se dublează

(exponenţial backoff) icircn RFC 793 dimensiunea maximă recomandată este de 2 minute

icircnsă icircn RFC 1122 se specifică că maximul este acelaşi cu cel din cazul retransmisiei (240

secunde)

2 receptorul trebuie să refuze aceste pachete răspunzacircnd cu segmente de confirmare care

indică neprimirea octetului respectiv

Observaţie timer-ul special necesar pentru implementare la transmiţător a comportamentului de mai sus este cunoscut sub numele de ``TCP Persistent Timer Numele este justificat de faptul că sondarea deschiderii se va face pacircnă cacircnd fie fereastra se deschide fie conexiunea se icircntrerupe TCP Keepalive Timer

Un lucru interesant despre TCP este faptul că dacă nivelele superioare nu comunică nimic icircntre

ele pentru o perioadă lungă 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 icircn care au trecut cu succes de faza stabilirii legăturii Dacă nivelurile

inferioare (reţeaIP fizic) devin temporar indisponibile cacirct tip cei doi nu vor să comunice atunci

acest lucru nu va perturba icircn nici un fel activitatea şi acest lucru este acceptabil Problemele

icircncep să apară icircn momentul icircn care cei doi doresc să comunice şi nivelele inferioare nu mai

permit acest lucru Evident că cel care va dori să comunice ceva va detecta icircntreruperea legăturii

şi va icircnchide conexiunea Ce se icircntacircmplă icircnsă dacă celălalt capăt nu are nimic de comunicat (de

exemplu este un server care oferă anumite servicii) Pentru el legătura va fi icircn continuare activă

şi icircn general anumite resurse vor fi rezervate pentru aceasta Rezolvarea acestei situaţii este dată

de introducerea unei mecanism de sondare a stării legăturii pe baza unui timer (TCP Keepalive

Timer) care se declanşează din două icircn două ore La fiecare expirare a timer-ului se trimite un

segment fără date care confirmă datele primite pacircnă atunci Răspunsul care trebuie primit este tot

un segment fără date care confirmă datele primite de partener (practic o re-publicare a stării celor

doi parteneri) Dacă răspunsul nu este primit timp de 75 secunde atunci segmentul va fi retrimis

Dacă după 10 astfel de icircncercări tot nu s-a primit nici un răspuns atunci conexiunea se va

considera terminată şi se va anunţa nivelul superior asupra acestui lucru

Observaţii

dacă o staţie primeşte segmente de keepalive despre conexiuni care nu mai sunt active

(de exemplu a fost resetat) atunci va răspunde cu segmente de reset (acesta e un procedeu

standard)

RFC 1122 specifică că facilitatea de keepalive trebuie activată icircn mod explicit

3 Studii de caz

Subsections

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

1 Fragmentarea pachetelor UDP

Deoarece UDP-ul este un serviciu fără conexiune toate datele pe care le primeşte de la nivelul

superior sunt icircncapsulate icircntr-o singură datagramă UDP care apoi va forma un pachet IP Dacă

pachetul IP astfel obţinut este prea mare atunci mecanismele IP de fragmentare icircl vor sparge icircn

bucăţi Exemplul următor icircncearcă să studieze exact acest fenomen

Pe maşina athos rulează un server de UDP pe portul 50007 Pe o altă maşină frodo aflată icircn

reţeaua locală este rulat un client care poate fi configurat să trimită un pachet UDP de o anumită

lungime Pentru a putea observa ce se icircntacircmplă pe athos este rulat tcpdump

Deoarece MTU-ul pentru o reţea Ethernet este icircn general 1500 şi antetul IP plus cel UDP ocupă

20 + 8 = 28 octeţi o datagramă UDP de dimensiune 1472 ar trebui sa fie trimisă nefragmentată

Pentru siguranţă folosind clientul de pe athos s-a trimis mai icircntacirci o datagramă UDP cu 1471

octeţi de date şi apoi icircncă una cu 1472 Pentru ambele tcpdump a indicat trimiterea lor fără

fragmentare

182556721144 frodonoi33274 gt athosnoi50007 udp 1471 (DF) (ttl 64 id

51481 len 1499)

182559846764 frodonoi33274 gt athosnoi50007 udp 1472 (DF) (ttl 64 id

51793 len 1500)

La o dimensiune de 1473 ar trebui ca trimiterea să genereze două pachete IP unul care să

conţină primii antetul UDP plus primii 1472 octeţi de date şi icircncă un pachet IP care conţine un

singur octet Iată ce indică tcpdump-ul

182605705813 frodonoi gt athosnoi udp (frag 3627411480) (ttl 64 len

21)

182605706116 frodonoi33274 gt athosnoi50007 udp 1473 (frag

3627414800+) (ttl 64 len 1500)

Intr-adevăr au fost generate două pachete IP

primul conţine doar un singur octet de date şi reprezintă ultimul fragment (bitul de more

fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest

lucru) care a fost spartă icircn bucăţi deplasamentul octetului primit in datagrama originală

este 1480

al doilea pachet este primul fragment din datagrama UDP şi conţine antetul UDP (din

cauza asta datele efective ocupă doar 1480 octeţi) deplasamentul este 0 şi bitul de more

fragments este setat (acest lucru este indicat de semnul ``+ de după deplasament)

După cum se poate observa ambele pachete poartă acelaşi număr de identificare (36274) Acest

lucru icircmpreună cu informaţiile date de flag-ul more fragments permite reconstrucţia la

destinaţie a datagramei UDP originale O problemă a acestui mod de fragmentare e că icircn cazul

pierderii unui fragment icircntreaga datagramă va fi compromisă şi va trebui retrimisă icircn icircntregime

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 5: udp tcp

2 TCP

Subsections

1 Caracteristici TCP

2 Formatul pachetelor TCP

3 Iniţierea şi terminarea unei conexiuni TCP

o Protocolul de iniţiere

1 Deschiderea simultană

o Protocolul de terminare

2 Terminarea simultană

3 Resetarea conexiunii

o Diagrama de stări

4 Controlul fluxului

o Icircntacircrzierea confirmărilor

o Algoritmul Nagle

o Fereastra glisantă

o Slow start

o Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

o Evitarea congestiei

o Fast Retransmission Fast Recovery

o Sindromul ``Silly Window

o TCP Keepalive Timer

1 Caracteristici TCP

Deoarece protocolul IP este de tip datagramă utilizarea lui direct icircn aplicaţii care in general au

nevoie de conexiuni sigure este mult prea anevoioasă Din aceste motive peste IP a fost construit

un alt protocol TCP (transimission control protocol) care corectează aceste probleme Prima

definire se găseşte icircn RFC-ul cu numărul 793 şi datează din septembrie 1981 Din cauza deselor

congestii apărute icircn 1986 algoritmul care stă la baza TCP-ului este reanalizat şi icircn octombrie

1989 icircn RFC-ul cu numărul 1122 este publicată o nouă specificare mult mai eficientă şi

neambiguă a TCP-ului Noi probleme legate de viteze mari sunt tratate icircn RFC-ul 1323 iar icircn

2018 TCP-ul este extins pentru a permite confirmările selective (selective acknowledge) Seria

de RFC-urie fundamentale este icircncheiată de apariţia icircn 1989 a RFC-ului cu numărul 2581 Icircn el

se specifică foarte strict comportamentul care este permis pentru o implementare de TCP

Alături de protocolul UDP TCP se situează pe nivelul transport icircn ierarhia de protocoale deci

icircntre nivelul aplicaţie şi nivelul reţea Dar cu toate că se bazează pe acelaşi protocol (IP) ca şi

UDP TCP furnizează către nivelul aplicaţie cu totul alt tip de servicii servicii orientate-

conexiune sigure de tip flux de octeţi

Termenul de orientat-conexiune presupune că icircntre cele două aplicaţii care comunică utilizacircnd

TCP trebuie să se stabilească o conexiune TCP icircnainte ca transferul de date să aibă loc Această

conexiune nu este efectiv una fizică ci virtuală asemănător cum se icircntacircmplă icircn sistemul de

telefonie clasică cineva formează un număr şi abia icircn momentul icircn care cealaltă persoană

răspunde se poate icircncepe conversaţia Fiind o conexiune host-la-host nu există noţiunile de

broadcast sau multicast

Transferul sigur de date este asigurat icircn următorul mod

Datele sunt icircmpărţite icircn bucăţi a căror dimensiune optimă e determinată de TCP spre

deosebire de UDP care trimite datagrame UDP corespunzătoare cu dimensiunea datelor

primite de la nivelul aplicaţie Unitatea de date trimisă de TCP către nivelul reţea poartă

numele de segment

Cacircnd TCP trimite un segment porneşte un timer şi dacă nu se primeşte confirmarea

segmentului respectiv icircntr-un anumit timp icircl retransmite

Icircn momentul icircn care se primeşte un segment TCP trimite o confirmare (din motive de

eficienţă aceasta poate fi amacircnată un anumit interval de timp)

Icircn headerul TCP este menţinută o sumă de control pentru detectarea modificărilor icircn date

Dacă se recepţionează un segment corupt TCP icircl ignoră urmacircnd să fie retransmis datorită

neprimirii confirmării

Deoarece segmentele TCP sunt transmise mai departe icircncapsulate icircn datagrame IP iar

acestea pot ajunge icircn orice ordine segmentele TCP pot ajunge icircn altă ordine decacirct cea icircn

care au fost trimise De aceea la destinaţie TCP-ul trebuie să se folosească de numere de

secvenţă pentru a reordona eventual segmentele icircnainte de a le livra către nivelul

aplicaţie De asemenea TCP trebuie să asigure ignorarea duplicatelor

TCP asigură controlul fluxului icircn condiţiile icircn care viteza de trimitere a datelor de la sursă

poate fi mult prea mare decacirct capacitatea de prelucrare de la destinaţie

Serviciul oferit de TCP este de tip flux de octeţi deoarece oferă garanţii că fluxul de date trimis

de sursă va fi livrat fără modificări la destinaţie Comparativ UDP-ul produce pentru fiecare

transfer cerut de nivelul aplicaţie un pachet IP (care ulterior poate fi supus fragmentării) care

dacă ajunge la destinaţie corect va fi livrat direct nivelului aplicaţie fără a garanta icircn vreun fel

ordinea

2 Formatul pachetelor TCP

Pachetele de date transmise de TCP segmentele sunt formate dintr-un antet (figura 72) de 20

octeţi urmat de datele primite de la nivelul aplicaţie Antetul poate uneori conţine şi o serie de

opţiuni caz icircn care poate ajunge la 60 octeţi

Figura 72 Structura unui segment TCP

Antetul unui segment TCP cuprinde

port sursă - 16 biţi pentru specificarea portului aplicaţiei transmiţătoare

port destinaţie - 16 biţi pentru specificarea portului aplicaţiei ce recepţionează segmentul

TCP

Aceste două porturi icircmpreună cu adresele ale sursei şi destinaţiei conţinute icircn antet-ul IP

identifică icircn mod unic conexiunea Pentru o pereche formată dintr-o adresă IP şi un port

se foloseşte adesea denumirea de socket (denumire introdusă icircn specificaţiile iniţiale ale

protocolului TCP icircn RFC 793)

număr de secvenţă - 32 biţi

Pentru a asigura un serviciu de tip flux de octeţi TCP numerotează fiecare octet de date

utilizacircnd un număr de secvenţă Numărul de secvenţă din cadrul antetului TCP specifică

destinaţiei care este primul octet din fluxul trimis La iniţierea unei conexiuni se setează

flag-ul SYN şi se alege aleator un număr de secvenţă de icircnceput utilizacircnd un generator de

numere de secvenţă ISN (Initial sequence number) Numărul de secvenţă al primului

octet de date va fi numărul generat ISN plus 1 deoarece pachetul de iniţiere (cu SYN

setat) consumă şi el un număr de secvenţă Se va vedea mai departe că şi flag-ul de

terminare a conexiunii FIN consumă şi el un număr de secvenţă

confirmare - 32 biţi

Reprezintă numărul de secvenţă al octetului de date pe care transmiţătorul confirmării se

aşteaptă să-l primească Astfel dacă s-a recepţionat octetul cu numărul de secvenţă x (icircn

numerotaţia sursei) pachetul de confirmare va avea flag-ul ACK setat şi va conţine

numărul de confirmare x + 1 Trimiterea unui ACK nu consumă un număr de secvenţă

deoarece atacirct acest cacircmp cacirct şi flag-ul ACK fac parte din antet şi după stabilirea

conexiunii ambele cacircmpuri devin active Acest mecanism nu permite confirmări selective

pentru că numărul de secvenţă specifică pacircnă unde s-au recepţionat date De exemplu

dacă la destinaţie au ajuns octeţii 1-1024 şi următorul segment primit conţine octeţii

2049-3072 nu se poate trimite confirmare pentru cel de-al doilea segment deci

confirmarea va cuprinde numărul de secvenţă 1025

lungimea antetului - 4 biţi

Specifică dimensiunea antetului ca număr de cuvinte de 32 de biţi (4 octeţi) Antetul

poate avea icircntre 20 şi 60 de octeţi deci valoarea acestui cacircmp va fi icircntre 5 (5 x 4 = 20

octeţi) şi 15 (15 x 4 = 60)

6 biţi rezervaţi pentru utilizări viitoare

6 biţi de control reprezentacircnd următoarele flag-uri ce pot fi setate simultan

o URG - cacircmpul urgent pointer este valid

o ACK - cacircmpul de confirmare este valid

o PSH - destinaţia trebuie să trimită datele către nivelul aplicaţie cacirct mai devreme

o RST - se doreşte resetarea conexiunii

o SYN - iniţierea conexiunii

o FIN - icircnchiderea conexiunii

dimensiunea ferestrei - 16 biţi

Reprezintă numărul de octeţi (icircncepacircnd cu numărul de secvenţă conţinut icircn cacircmpul de

confirmare) pe care destinaţia e dispusă să-l primească Este limitat la 65535 octeţi dar

cu toate că pare o limită destul de mare există situaţii cacircnd se doresc valori mult mai

mari Icircn acest scop se folosesc nişte opţiuni speciale descrise ceva mai tacircrziu care permit

scalarea ferestrei

suma de control - 16 biţi

Această sumă de control acoperă icircntregul segment TCP (atacirct datele cacirct şi antetul TCP) şi

spre deosebire de UDP este obligatoriu să fie completat de transmiţător şi verificat de

receptor Dar ca şi icircn cazul UDP-ului la calculul sumei de control se ia in considerare şi

o zona specială de 12 octeţi ce cuprinde pentru re-verificare cacircmpuri din antetul IP

(adresa IP a sursei şi a destinaţiei)[aici tre sa vina o referire la poza cu pseudo-antetu]

După adăugarea acestui pseudo-antet datele se icircmpart icircn cuvinte de 16 biţi icircn vederea

calculării sumei de control adăugacircndu-se eventual şi un octet de aliniere

urgent pointer - 16 biţi

Este utilizat pentru specificarea deplasamentului ultimului octet de date trimis icircn regim

urgent Astfel ultimul octet din secvenţa urgentă se obţine adunacircnd acest cacircmp la

numărul de secvenţă Ce icircnseamnă acest mod urgent de transmitere există situaţii icircn care

aplicaţiile vor să trimită date `neordonate` Să presupunem că aplicaţia a trimis către

nivelul transport o cantitate mare de date dar la un moment dat observă ceva icircn neregulă

şi doreşte să anuleze operaţia Dacă trimite o comandă de anulare aceasta va fi adăugată

la sfacircrşitul şirului de octeţi deci nu se va putea icircmpiedica ajungerea acestora la nivelul

aplicaţie de la receptor Activacircnd modul urgent datele urgente (comanda de anulare) vor

fi plasate la icircnceputul pachetului Aplicaţiile mai cunoscute care folosesc acest mod sunt

Telnet Rlogin şi FTP

opţiuni - pacircnă la 40 de octeţi (figura 73)

Cele mai utilizate opţiuni sunt

o Sfacircrşit de opţiuni (end of option) - 1 octet

Este utilizat pentru alinierea datelor conţinute icircn cacircmpul de opţiuni Nu poate fi

utilizat decacirct o singură dată marcacircndu-se astfel sfacircrşitul opţiunilor şi icircnceperea

datelor efective Dacă pentru alinierea la un cuvacircnt de 32 de biţi e nevoie de mai

mult de 1 byte se va utiliza opţiunea no operation Orice apare după această

opţiune pacircnă la icircnceputul cuvacircntului următor de 32 de biţi e ignorat

o no operation - 1 octet

Utilizat pentru alinierea la cuvinte de 32 de biţi

o Dimensiunea maximă a segmentului (Maximum Segment Size (MSS)) - 16 biţi

Icircn ciuda denumirii defineşte lungimea maximă a datelor nu dimensiunea

icircntregului segment Poate lua valori icircntre 0 şi 65535 valoarea implicită fiind 536

Această opţiune e valabilă doar icircn pachetele de iniţiere a conexiunii (cele cu flag-

ul SYN setat) fiecare parte făcacircnd cunoscută dimensiunea maximă a datelor

dispusă să le primească icircntr-un pachet Icircn principiu cu cacirct această valoarea e mai

mare e mai bine (deoarece se recuperează din spaţiul ocupat de antetele TCP şi

IP) pacircnă cacircnd apare fragmentarea Valoarea maximă la care se poate seta este

MTU (Maximum Transfer Unit) minus dimensiunea antetului IP şi TCP (1460

octeţi icircn cazul Ethernet)

o Factor de scalare a ferestrei (Window scale factor) - 1 octet

Pentru situaţiile icircn care se doreşte utilizarea unei ferestre mai mare de 65535 bytes

se poate utiliza acest cacircmp pentru mărirea dimensiunii ferestrei Noua dimensiune

va fi Chiar dacă

factorul de scalare poate fi maxim 255 icircn cazul TCPIP el nu poate depăşi

valoarea 16 deoarece dimensiunea maximă a ferestrei nu poate fi mai mare decacirct

valoarea celui mai mare număr de secvenţă ( )

Acest factor se poate seta doar la iniţierea conexiunii Icircn timpul transferului de

date se poate modifica dimensiunea ferestrei dar factorul de scalare rămacircne

acelaşi Dacă cel care a iniţiat conexiunea a trimis icircn segmentul de iniţiere şi acest

factor dar icircn pachetul cu ACK destinatarul nu şi-a trimis şi el factorul atunci se la

considera 0 icircn ambele direcţii Invers dacă cel care solicită deschiderea

conexiunii nu setează factorul destinaţia nu va putea seta factorul de scalare

o Timestamp - 10 octeţi

Utilizat pentru reţinerea timpului icircn vederea calculării RTT (Round Trip Time)

Cacircmpul timestamp e completat de sursă icircn momentul trimiterii segmentului La

destinaţie valoarea este reţinută şi copiată icircn cacircmpul timestamp echo reply al

pachetului cu confirmarea RTT-ul este calculat de sursă făcacircnd diferenţa dintre

timpul curent şi această valoare

Figura Opţiuni TCP

3 Iniţierea şi terminarea unei conexiuni TCP

TCP este un protocol orientat conexiune deci presupune stabilirea unei căi virtuale icircntre sursă şi

destinaţie

Subsections

Protocolul de iniţiere

o 1 Deschiderea simultană

Protocolul de terminare

o 2 Terminarea simultană

o 3 Resetarea conexiunii

Diagrama de stări

Protocolul de iniţiere

Modul de transmisie icircn cazul protocolului TCP este full-duplex deci sunt transmise date

simultan icircn ambele direcţii Aceasta presupune că cel care iniţiază conexiunea trebuie să

primească aprobarea celuilalt capăt icircnainte de icircnceperea transferului de date sursa icircşi anunţă

intenţia de a iniţia o conexiune destinaţia trimite un pachet cu confirmarea cererii şi un pachet de

iniţiere a conexiunii de la el la sursă iar apoi sursa confirmă cererea primită de la destinaţie Paşii

2 şi 3 pot fi realizaţi prin trimiterea unui singur pachet de aceea protocolul de iniţiere este

cunoscut sub numele de three-way handshake

Icircn cadrul protocolului de iniţiere există 2 tipuri de cereri de iniţiere cerere activă (active open)

iniţiată de clientul ce doreşte să stabilească conexiunea cu serverul şi cerere pasivă (passive

open) din partea serverului

Cei 3 paşi sunt

1 Clientul trimite un segment cu flag-ul SYN setat şi care conţine portul sursă portul de la

destinaţie şi numărul de secvenţă generat iniţial (ISN) de la care se vor numerota octeţii

de la client către server Opţional se pot stabili parametrii conexiunii prin setarea lungimii

maxime a segmentelor (MSS) dispus să le primească de la server factorului de scalare a

ferestrei Acest prim segment nu conţine nici un parametru de confirmare şi de asemenea

nu are rost să conţine să seteze dimensiunea ferestrei

2 Al doilea segment e trimis de server şi are un rol dublu confirmă segmentul primit de la

client prin setarea flag-ului ACK şi completează numărul de secvenţă cu numărul de

secvenţă primit plus 1 şi al doilea rol iniţializează conexiunea de la el către client prin

setarea flag-ului SYN şi generarea unui număr de secvenţă iniţial ce va fi folosit icircn

numerotarea octeţilor de la server spre client Pe lacircngă aceasta trebuie să conţină

dimensiunea ferestrei şi opţional poate seta factorul de scalare şi dimensiunea maximă a

segmentului acceptat

3 Clientul trimite un segment cu confirmarea cererii din partea serverului (ACK setat +

completează numărul confirmat cu numărul de secvenţa primit + 1) Ca şi icircn cazul

pasului 2 trebuie să seteze dimensiunea ferestrei Acest pachet poate conţine date

Subsections

1 Deschiderea simultană

1 Deschiderea simultană

Se poate icircntacircmpla ca uneori cele două capete care vor să comunice să icircncerce să stabilească

conexiunea simultan Icircn acest caz după ce fiecare a trimis segmentul de iniţiere (iniţiere activă)

ambele vor trimite un segment cu SYN + ACK şi se va stabili o singură conexiune nu două

Protocolul de terminare

Oricare dintre cele două părţi poate solicita icircnchiderea conexiunii dar conexiunea fiind full-

duplex transferul de date icircn celălalt sens poate continua (această situaţie e denumită half-close)

O icircnchidere completă a unei conexiuni TCP presupune următorii paşi

1 Clientul trimite un segment cu flag-ul FIN activat solicitacircnd icircnchiderea conexiunii

2 Serverul trimite un segment ACK confirmacircnd primirea cererea Numărul de confirmare

se completează normal ca numărul de secvenţă primit + 1

3 Serverul continuă să trimită date către client şi cacircnd doreşte să icircnchidă şi el conexiunea

trimite un segment cu FIN activat

4 Clientul trimite un pachet ACK confirmacircnd icircnchiderea conexiunii

Cel care iniţiază primul procedura de icircnchidere (trimite primul FIN) realizează o icircnchidere activă

(active close) iar celălalt capăt o icircnchidere pasivă (passive close) Icircn mod normal cel care

realizează iniţierea activă va fi primul ce va trimite FIN dar oricare dintre cei doi poate icircnchide

activ conexiunea

Subsections

2 Terminarea simultană

3 Resetarea conexiunii

2 Terminarea simultană

Icircn mod similar cu deschiderea simultană există posibilitatea ca ambele capete ale conexiunii TCP

să iniţieze simultan procedura de icircnchidere a conexiunii Icircn acest caz ambele părţi vor trimite

FIN şi vor aştepta primirea unui ACK Icircn continuare fiecare va primi cererea de terminare şi va

trimite ACK Se observă că numărul de segmente transferate pentru realizarea icircnchiderii

conexiunii (4 segmente) este acelaşi ca la terminarea normală

3 Resetarea conexiunii

Există situaţii icircn care TCP doreşte resetarea conexiunii De exemplu dacă se solicită iniţierea

unei conexiuni la un port inexistent Icircn acest caz cealaltă parte va trimite un segment cu bitul

RST setat pentru a anula solicitarea O altă situaţie este atunci cacircnd se constată că celalalt capăt

al conexiunii nu răspunde un anumit timp (timeout)

Diagrama de stări

Toate evenimentele ce au loc icircn timpul stabilirii conexiunii transferului şi icircnchiderii conexiunii

pot fi rezumate printr-un automat finit cunoscut sub numele de diagrama de stări După cum

chiar numele sugerează este o maşină cu un număr limitat de stări O stare este păstrată pacircnă icircn

momentul apariţiei unui eveniment moment icircn care se poate trece icircn altă stare şisau efectua o

acţiune

Aceste stări posibile sunt (denumirile sunt asemănătoare cu cele utilizate de netstat) cele din

tabelul 71

Tabela Stările diagramei de stări TCP

Stare Descriere

CLOSED Nu există conexiune

LISTEN Serverul aşteaptă cereri de la clienţi

SYN_SENT Cerere de iniţiere (activă) a conexiunii Se

aşteaptă confirmarea

SYN_RCVD S-a primit o cerere de iniţiere conexiune

ESTABLISHED S-a stabilit conexiunea

FIN_WAIT_1 Aplicaţia a solicitat icircnchiderea conexiunii

FIN_WAIT_2 Serverul a acceptat icircnchiderea conexiunii

CLOSING Ambele părţi solicită simultan icircnchiderea

conexiunii

TIME_WAIT Conexiune icircnchisă dar se aşteaptă ca

pachetele retransmise să dispară

CLOSE_WAIT Serverul aşteaptă icircnchiderea dinspre partea

aplicaţiei

LAST_ACK Serverul a icircnchis conexiunea Aşteaptă

ultima confirmare

Icircn diagrama ilustrată icircn figura 74 putem observa 3 tipuri de tranziţii icircntre cele 11 stări tranziţii

ce corespund unei funcţionări normale pentru client (linii normale continue) pentru server (linii

normale icircntrerupte) şi tranziţii pentru situaţii nestandard (linii subţiri continue)

O comportarea normală pentru client presupune parcurgerea următoarelor stări CLOSED

SYN_SEND ESTABLISHED FIN_WAY_1 FIN_WAY_2 TIME_WAIT

Iniţial clientul TCP se află icircn starea CLOSED

Aşteptacircnd icircn starea CLOSED clientul poate primi de la aplicaţie o cerere de iniţiere

activă a unei conexiuni Trimite un segment SYN şi trece icircn starea SYN_SENT

Icircn starea SYN_SENT clientul aşteaptă de la server un segment ACK+SYN după care

trimite un ACK şi trece icircn starea ESTABLISHED Din acest moment poate icircncepe

transferul efectiv de date Clientul va rămacircne icircn această stare cacirct timp are de trimisprimit

date

Aflat icircn această stare clientul TCP poate primi din partea aplicaţiei o cerere de icircnchidere a

conexiunii Icircn acest caz va trimit un segment FIN şi trece icircn starea FIN_WAIT_1

Icircn această stare clientul aşteaptă ACK din partea serverului După ce-l primeşte

conexiunea icircntr-un sens se va icircnchide şi clientul trece icircn starea FIN_WAIT_2

Starea FIN_WAIT_2 durează pacircnă cacircnd primeşte cererea de icircnchidere a conexiunii FIN

din partea serverului Trimite ACK şi va trece icircn starea TIME_WAIT

Icircn această stare se va porni un timer cu valoarea setată la dublul timpului de viaţă estimat

pentru un segment de lungime maximă MSL (Maximum Segment Lifetime) Acest timer

permite retransmiterea ACK-ului icircn cazul icircn care acesta se pierde (celălalt capăt va da

timeout şi va retransmite segmentul FIN) Icircn tot acest time cei doi sockeţi (de la client şi

server) nu vor putea fi reutilizaţi Totodată pachetele icircntacircrziate care sosesc icircn această

perioadă sunt ignorate După expirarea acestui timer clientul revine icircn starea iniţială

CLOSED

Din punctul de vedere al unui server o comportare standard parcurge următoarele stări

CLOSED LISTEN SYN_RCVD ESTABLISHED CLOSE_WAIT şi LAST_ACK

Iniţial serverul TCP se află icircn starea CLOSED

Icircn această stare poate primi de la aplicaţia server o cerere de iniţiere activă şi trece icircn

starea LISTEN

Aflat icircn starea LISTEN serverului TCP poate recepţiona un segment SYN de la un client

TCP Icircn acest caz va trimite ACK+SYN şi va trece icircn starea SYN_RCVD

Icircn această stare serverul aşteaptă primirea confirmării de la client moment icircn care

conexiunea e stabilită icircn ambele sensuri şi se poate icircncepe transferul de date (starea

ESTABLISHED)

Clientul TCP poate solicita icircnchiderea conexiunii trimiţacircnd un segment FIN către server

Icircn acest caz serverul TCP trimite confirmarea şi trece icircn starea CLOSE_WAIT

Icircn această stare serverul aşteaptă să primească din partea programului server icircnchiderea

conexiunii moment icircn care va trimite către client un segment FIN şi trece icircn starea

LAST_ACK

Serverul aşteaptă primirea ultimei confirmări de la client după care revine icircn starea

CLOSED

Atacirct serverul cacirct şi clientul TCP se pot afla icircn oricare din cele 11 stări ale diagramei

Figura Diagrama de stări pentru TCP

4 Controlul fluxului

Dacă icircncă de la icircnceput s-a reuşit stabilirea formatului unui pachet TCP şi a modulului icircn care

trebuie să se facă icircnchiderea şi deschiderea unei conexiuni nu acelaşi lucru se poate spune şi

despre modul icircn care ar trebui să se realizeze controlul fluxului Ţinacircnd seama icircnsă că din 1989

(de cacircnd datează RFC-ul 2581 cel despre care am menţionat că specifică icircn mod clar modul icircn

care trebuie să se comporte o implementare de TCP) TCP-ul a rămas neschimbat putem să icircl

considerăm un rezultat important al domeniului reţelor de calculatoare

Icircn cele ce urmează vom icircnţelege prin controlul fluxului totalitatea algoritmilor care permit

atingerea unei viteze de transfer punct-la-punct cacirct mai mare pentru toate conexiunile existente

Icircn principal aceşti algoritmi stabilesc modul icircn care segmentele şi confirmările trebuie trimise şi

ce acţiuni trebuie executate icircn situaţiile icircn care răspunsurile aşteptate de la celălalt capăt icircntacircrzie

să vină

Subsections

Icircntacircrzierea confirmărilor

Algoritmul Nagle

Fereastra glisantă

Slow start

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Evitarea congestiei

Fast Retransmission Fast Recovery

Sindromul ``Silly Window

TCP Keepalive Timer

Icircntacircrzierea confirmărilor

O modalitate simplă de generare a confirmărilor este de a trimite cacircte una pentru fiecare segment

primit Această politică prezintă avantajul de a face comunicaţia self-clocking icircnsă este

ineficientă dacă segmentele care nu conţin decacirct confirmări sunt urmate la scurtă distanţă (cacircteva

zeci de milisecunde) de segmente ce conţin date efective Pentru a evita această situaţie se

procedează2 la icircntacircrzierea (200ms este o valoare uzuală icircn RFC 1122 se specifică o valoare

maximă de 500ms) a segmentelor care conţin doar confirmări Această strategie face posibil ca

un răspuns generat de primirea unor date să plece sper celălalt capăt icircn acelaşi segment cu

confirmarea

Observaţie deoarece este dificil de menţinut timere pentru fiecare confirmare diferenţa de

200ms este calculată de un timer global Din acest motiv modul efectiv de comportare poate fi

descris şi icircn felul următor cacircnd un segment nu conţine decacirct o confirmare el este pus icircntr-o

coadă ce va fi inspectată de un proces care din 200 icircn 200 ms trimite tot ce s-a acumulat icircn

coada

Footnotes

2

Acest comportament a fost propus de David D Clark icircn iulie 1982 icircn RFC 813

Algoritmul Nagle

Acest algoritm3 icircncearcă să icircmbunătăţească performanţele exploatacircnd următoarea caracteristică

foarte des icircntacirclnită icircn dialogul dintre două staţii dacă se icircncearcă trimiterea unor date de

dimensiune mică icircnsă există icircncă date neconfirmate de partener atunci ele sunt buffer-ate şi

trimise icircntr-un segment mai mare cacircnd soseşte confirmarea aşteptată Icircn acest fel se poate evita

generarea datagramelor mici (tinygrame) icircn situaţia unei legături lente Icircn cazul unei legături

rapide confirmările vor veni repede şi icircntacircrzierea introdusă de algoritm va neglijabilă

Există icircnsă şi cazuri icircn care acest algoritm duce la deprecierea performanţelor mesajele scurte

generate de mişcările mouse-ului icircn cazul folosirii unui server X Window sau utilizarea tastelor

care trimit mai mult de un caracter (secvenţe escape) Pentru a rezolva aceste inconveninte API-

ul de utilizare a TCP-ului trebuie să ofere o modalitate de a dezactiva acest algoritm (icircn sistemele

bazate pe sockeţi există icircn acest scop opţiunea TCP_NODELAY)

Footnotes

algoritm3

Algoritmul aparţinacircnd lui John Nagle a fost propus icircn ianuarie 1984 icircn RFC 896

Fereastra glisantă

Algoritmul implementat de TCP pentru a implementa transferul sigur de date este cunoscut icircn

teorie sub numele de Go-Back-N Icircn acest algoritm se utilizează numere de secvenţă pentru a

distinge pachetele icircntre ele şi o coadă (dimensiunea maximă a cozii reprezintă fereastra) de

pachetele a căror confirmare se aşteaptă Pachetele se icircmpart icircn 4 categorii

1 pachete trimis şi pentru care s-a primit confirmare

2 pachete trimise şi pentru care se aşteaptă icircncă confirmarea

3 pachete care nu au fost trimise icircncă dar care nu depăşesc limitele ferestrei şi deci pot fi

trimise

4 pachete care icircncă nu au fost trimite şi care nici nu vor putea fi trimise decacirct după ce au

fost trimise toate pachetele din categoria 3 şi s-au primit o parte din confirmările la

pachetele din categoria 2

Dacă confirmările pentru pachetele din categoria 2 icircntacircrzie prea mult (un mecanism de timer-e

informează asupra acestui lucru) atunci ele vor fi retrimise Icircn versiunea iniţială TCP-ul nu

permitea decacirct confirmări pozitive ceea ce icircnseamnă că avansarea ferestrei se va icircmpotmoli la

segmentele neconfirmate Cum se poate evita aceasta situaţie vom discuta icircn detaliu icircn capitolele

următoare O soluţie foarte radicală o constituie introducerea de confirmări selective (acest lucru

este realizat de RFC 2018 din octombrie 1996) Această modifică face ca TCP-ul actual să fie un

hibrid de Go-Back-N şi Selective Repeat

Deoarece dimensiunea ferestrei este anunţată la fiecare segment un client lent poate ca pe măsură

ce trimite confirmările să informeze despre progresul icircnregistrat la livrarea datelor următorului

nivel (aplicaţie) Dacă datele vin prea repede pentru viteza cu care clientul procesează datele

fereastra fereastra se va dimiua şi chiar icircnchide (acest lucru se realizează anunţacircnd o fereastră de

dimensiune zero) Cum se realizează efectiv redeschiderea vom analiza icircntr-un capitol viitor

Slow start

Un transfer de date TCP poate să icircnceapă prin transmiterea de segmente pacircnă la umplerea

icircntregii ferestre după care fie se primesc confirmări care vor permite unor noi pachete să fie

trimise fie vor expira timer-ele de retransmisie şi se va icircncepe retrimiterea pachetelor de la

icircnceputul ferestrei Din păcate un astfel de comportament poate duce la pomparea icircn reţea a unui

număr de pachete prea mare pentru capacitatea disponibilă efectiv icircnrăutăţind congestia Pentru

a evita acest lucru s-a propus următoarea soluţie4 iniţial se trimite un segment după primirea

confirmării lui se trimit două segmente după sosirea confirmărilor pentru ele se trimit patru

segmente şi aşa mai departe La un moment dat fie vor icircncepe să se piardă segmente (un indiciu

că s-a atins capacitatea maximă a canalului) fie se va umple fereastra pe care o anunţă cel care

primeşte Trebuie să remarcam că datorită creşterii exponenţiale a numărului de segmente se va

atinge destul de repede una din cele două situaţii

Modalitatea efectivă de implementare a acestui algoritm are la bază utilizarea unei ferestre de

congestie (congestion window cwnd) care este iniţializată cu dimensiunea unui segment (cwnd

se calculează icircn octeţi) şi la fiecare pas este dublată fereastra efectivă din cadrul căreia se pot

trimite segmente este dată de minimul dintre ultima fereastra comunicată de partener şi cwnd

Footnotes

soluţie4

Soluţia aparţine lui V Jacobson şi a fost prezentată icircn 1988 la conferinţă ACM

SIGCOMM-88

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Deoarece TCP trebuie să funcţioneze icircn condiţii variate de latenţă modul icircn care se face

retransmiterea trebuie să fie cacirct mai flexibil (şi simplu icircn acelaşi timp pentru a introduce un

overhead cacirct mai mic) Timpul cacirct se aşteaptă venirea unei confirmări (retransmission timeout

RTO) este calculat prin cronometrarea timpului care icirci ia unui segment trimis să fie confirmat

Pentru o anumită conexiune se cronometrează cacircte un singur segment la un moment dat iar pe

baza RTT-ului măsurat se actualizează valoare RTO-ului

Icircn RFC 793 formula de calcul a RTO-ului este următoarea

unde este ultimul RTT măsurat este o estimare ponderată pentru RTT este un coeficient

de ponderare care icircn general are valoarea iar este un coeficient cu o valoare recomandată

de După cum se poate observa icircn valoarea lui este inclusă icircn mare măsură vechea valoarea

Icircn acest fel ajustarea RTT-ului se face treptat Din păcate acest mod de calcul nu funcţionează

bine la variaţii mari ale RTT-ului ducacircnd la creşterea numărului de retransmisii exact atunci

cacircnd fenomenul de congestie icircncepe să apară

Pentru a remedia aceste neajunsuri V Jacobsen a propus icircn 1988 o nouă metodă de calcul o

metodă care ţine seama seamă şi de modul icircn care variază diferenţa dintre RTT-uri Formulele

folosite sunt următoarele

unde este un estimare pentru media RTT-urilor este o estimare pentru abaterea RTT-urilor

faţă de medie (o aproximaţie suficientă pentru abaterea pătratică medie care icircnsă este mult mai

costisitor de calculat) este diferenţa dintre RTT-ul măsurat ( ) şi estimarea curentă ( )

Coeficientul cu care este actualizată estimarea curentă are valoarea de iar cel cu care este

actualizat estimarea abaterii este La stabilirea unei conexiuni valorile pentru şi sunt

alese astfel icircncacirct să rezulte un RTT de secunde şi un de 3 secunde (aceste recomandări

sunt făcute de RFC 1122)

Dacă pentru un anumit segment nu se primeşte confirmarea icircn intervalul indicat de el va fi

retrimis şi noul este dublat Valoarea maximă admisă pentru este de 240 secunde

Deoarece icircn cazul retrimiterilor nu se poate determina cu exactitate căruia din segmentele trimise

aparţine confirmarea actualizarea estimărilor este amacircnată pacircnă cacircnd se reuşeşte trimiterea

corectă (s-a primit confirmare) fără retransmitere(``din prima) a unui segment Acest artificiu

(deloc neimportant) care permite evitarea actualizarea eronată a estimărilor este cunoscut sub

numele de algoritmul lui Karn şi a fost propus icircn 1987 de P Karn şi C Partridge

Evitarea congestiei

Dacă cei doi parteneri care comunică prelucrează datele suficient de repede şi vor să transfere un

volum mare de date atunci limitarea de care se vor lovi este cea dată de viteza reţelei Din cauza

modului ``best-effort pe care IP-ul icircl oferă cacircnd canalul de comunicaţie este saturat o parte din

segmentele TCP se vor pierde Icircn mod poate paradoxal atacirct transmiţătorului cacirct şi receptorul se

pot afla icircn poziţia de a fi primii icircn detectarea pierderii unui segment Unul din indiciile de la

transmiţător care semnalează pierderea unui segment este (icircn mod evident) apariţia 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 icircn varianta iniţială nu

permite decacirct confirmări pozitive singurul lucru pe care receptorul icircl poate face este ca la fiecare

segment out-of-order primit să trimită o confirmare indicacircnd prin aceasta că la el continuă să

vină segmente icircnsă cel indicat de numărul de secvenţă de confirmare lipseşte Primirea acestor

confirmări multiple este al doilea mod icircn care transmiţătorul poate afla de apariţia congestiei

Algoritmul ce trebuie aplicat icircn momentul icircn care se detectează apariţia congestiei este cunoscut

sub numele de ``evitarea congestiei (congestion avoidence) Principiul care stă la baza lui este

ca la apariţia congestiei fie să se treacă la o incrementare liniară a dimensiunii ferestrei dacă

congestia a fost detectată ca urmare a primirii unor confirmări identice repetate fie să se reia

slow start-ul icircn cazul icircn care congestia s-a detectat prin expirarea unui timer de timeout

Implementarea acestui algoritm se bazează pe utilizarea unui nou contor (sstresh) care să indice

dimensiunea ferestrei de la care se trece de la incrementarea exponenţială la cea liniară

Algoritmul efectiv este următorul

1 la stabilirea unei noi conexiuni se pleacă cu sstresh iniţializat la valoare de 64K şi cwnd

la dimensiunea unui segment

2 trimiterea de segmente se face fără a depăşi minimul dintre fereastra publicată de partener

(pentru a nu depăşi capacitatea de procesesare a partenerului) şi cwnd-ul curent (pentru a

nu depăşi limita impusă de capacitatea reţelei)

3 la apariţia congestiei sstresh este setat la jumătatea valorii ferestrei curente (minimul

dintre fereastra anunţată de partener şi cwnd icircnsă cel puţin dimensiunea corespunzătoare

pentru două segmente) dacă congestia a fost detectată prin expirarea unui timer de

timeout atunci cwnd este iniţializat cu dimensiunea unui segment

4 la primirea unei confirmări incrementarea se face icircn două moduri icircn funcţie de relaţie icircn

care se află cwnd şi sstresh

1 dacă cwnd e mai mic sau egal cu sstresh se face incrementarea exponenţială

caracteristică slow start-ului (care de fapt nu e deloc slow icircn cazul de faţă)

2 dacă cwnd e mai mare ca sstresh atunci se face o incrementare cu dimensiunea

unui segment

Fast Retransmission Fast Recovery

După cum am văzut un receptor care primeşte segmente out-of-order va trimite transmiţătorului

confirmări duplicate Algoritmul denumit ``fast retransmission recomandă următoarele două

comportamenet

1 un receptor care detectează segmente out-of order trebuie să nu icircntacircrzie trimiterea de

confirmări (după cum am văzut icircn general confimările sunt icircntacircrziate micşora numărul de

pachete fără date care sunt transferate)

2 un transmiţător care care primeşte mai mult de trei confirmări duplicate trebuie să

retrimită segmentul indicat ca fiind neprimit de confirmările icircn cauză fără a aştepta

expirarea timer-ul de timeout

Algoritmul de ``fast recovery icircncearcă să optimizeze şi mai mult comportamentul

transmiţătorului care detectează un număr de trei sau mai multe confimări duplicate Mai exact el

recomandă trecerea la actualizarea liniară a ferestrei (congestion avoidance) Acest tip de

comportament se poate justifica prin următorul raţionament deoarece icircncă mai sunt transferate

date icircntre cei doi parteneri (şi acest lucru se icircntacircmplă sigur de vreme ce sosesc confirmări

duplicate icircn cazul acesta) icircnseamnă că transferul nu este afectat de o congestie severă şi prin

urmare trecerea la slow start nu e (icircncă) necesară (slow start-ul eliberează aproape complet

canalul deoarece cwnd este resetat la dimensiunea unui singur segment)

Cei doi algoritmi pot fi implementaţi icircn felul următor

1 cacircnd se detectează trei confirmări consecutive identice se setează sstresh la jumătate din

valoarea cwnd se retransmite segmentul care s-a pierdut şi se setează cwnd la valoarea

egală cu sstresh plus dimensiunea a trei segmente (acest lucru va face ca algoritmul de

incrementare a cwnd să treacă la incrementare liniară)

2 la fiecare confirmare duplicată care mai soseşte se incrementează cwnd se incrementează

cu dimensiunea unui segment

3 cacircnd icircncetează primirea de confirmări duplicate (segmentul retrimis a ajuns cu bine la

receptor şi s-a trimis o confirmare care acoperă segmentul care se pierduse iniţial) cwnd

este setat la valoarea sstresh

Sindromul ``Silly Window

Protocoalele bazate pe fereastră glisantă (cum este şi TCP-ul) pot să ajungă icircn situaţia deloc

fericită de trimite un număr mare de segmente mici icircn loc de segmente de dimensiune maximă

Acest tip de comportament este cunoscut sub numele de sindromul ``silly window

O modalitate prin care TCP-ul poate să cadă victimă acestui tip de comportament este

deschiderea de ferestre cu dimensiune foarte mică O altă situaţia nefericită este cea icircn care un

transmiţător este ``lacom şi trimite date indiferent de cacirct de mică este fereastra (după cum vom

vedea imediat uneori are sens şi un astfel de comportament) Algoritmul de evitare a acestor

neajunsuri este următorul

1 un receptor nu trebuie să anunţe deschideri de ferestre mici Mai exact nu se recomandă

anunţarea unei incrementări a ferestrei mai mică decacirct dimensiunea unui segment (MSS)

sau jumătate din buffer-ul aflat la dispoziţia receptorului oricare din ele e mai mică

2 un transmiţător va trimite date doar icircn următoarele cazuri

1 se poate trimite un segment icircntreg

2 se poate trimite jumătate din dimensiunea celei mai mari ferestre pe care

partenerul a publicat-o pacircnă acum

3 toate datele trimise pacircnă acum au fost confirmate sau algoritmul Nagle este

dezactivat şi se trimit toate datele care sunt icircn buffer-ul de trimitere

Cacircteva justificări cazul 2b tratează cazul icircn care partenerul anunţă ferestre mai mici decacirct

dimensiunea unui segment iar cazul 2c impune condiţiile respectării algoritmului Nagle după

cum se vede dacă algoritmul Nagle este activ şi s-au acumulat destul date mai exact cacirct

dimensiunea unui segment el va fi trimis chiar dacă există segmente neconfirmate Pentru

implementarea comportamentului impus de 2b un transmiţător trebuie să ţină evidenţa celei mai

mari ferestre pe care partenerul a anunţat-o Ţinacircnd seama că dimensiunea acestor buffer-e nu se

modifică acest mod de a icircncerca determinarea lor este suficient

O altă problemă legată tot de ferestre este cazul icircnchiderii acesteia Un mod icircn care s-ar putea

anunţa redeschiderea este trimiterea de către receptor a unei confirmări (duplicat) care să anunţe

redeschiderea la o anumită valoare a ferestrei Deoarece acest pachet nu trebuie confirmat icircn mod

special şi s-ar putea să se piardă se poate ajunge icircn situaţia icircn care receptorul a anunţat

redeschiderea ferestrei segmentul s-a pierdut iar transmiţătorul icircncă mai icircl mai aşteaptă pentru a

putea continua transferul Rezolvarea la această problemă s-a făcut prin impunerea unui alt

comportament

1 transmiţătorul va trimite segmente cu dimensiunea datelor de un octet prin care sondează

deschiderea ferestrei intervalul la care se sondează redeschiderea ferestrei se dublează

(exponenţial backoff) icircn RFC 793 dimensiunea maximă recomandată este de 2 minute

icircnsă icircn RFC 1122 se specifică că maximul este acelaşi cu cel din cazul retransmisiei (240

secunde)

2 receptorul trebuie să refuze aceste pachete răspunzacircnd cu segmente de confirmare care

indică neprimirea octetului respectiv

Observaţie timer-ul special necesar pentru implementare la transmiţător a comportamentului de mai sus este cunoscut sub numele de ``TCP Persistent Timer Numele este justificat de faptul că sondarea deschiderii se va face pacircnă cacircnd fie fereastra se deschide fie conexiunea se icircntrerupe TCP Keepalive Timer

Un lucru interesant despre TCP este faptul că dacă nivelele superioare nu comunică nimic icircntre

ele pentru o perioadă lungă 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 icircn care au trecut cu succes de faza stabilirii legăturii Dacă nivelurile

inferioare (reţeaIP fizic) devin temporar indisponibile cacirct tip cei doi nu vor să comunice atunci

acest lucru nu va perturba icircn nici un fel activitatea şi acest lucru este acceptabil Problemele

icircncep să apară icircn momentul icircn care cei doi doresc să comunice şi nivelele inferioare nu mai

permit acest lucru Evident că cel care va dori să comunice ceva va detecta icircntreruperea legăturii

şi va icircnchide conexiunea Ce se icircntacircmplă icircnsă dacă celălalt capăt nu are nimic de comunicat (de

exemplu este un server care oferă anumite servicii) Pentru el legătura va fi icircn continuare activă

şi icircn general anumite resurse vor fi rezervate pentru aceasta Rezolvarea acestei situaţii este dată

de introducerea unei mecanism de sondare a stării legăturii pe baza unui timer (TCP Keepalive

Timer) care se declanşează din două icircn două ore La fiecare expirare a timer-ului se trimite un

segment fără date care confirmă datele primite pacircnă atunci Răspunsul care trebuie primit este tot

un segment fără date care confirmă datele primite de partener (practic o re-publicare a stării celor

doi parteneri) Dacă răspunsul nu este primit timp de 75 secunde atunci segmentul va fi retrimis

Dacă după 10 astfel de icircncercări tot nu s-a primit nici un răspuns atunci conexiunea se va

considera terminată şi se va anunţa nivelul superior asupra acestui lucru

Observaţii

dacă o staţie primeşte segmente de keepalive despre conexiuni care nu mai sunt active

(de exemplu a fost resetat) atunci va răspunde cu segmente de reset (acesta e un procedeu

standard)

RFC 1122 specifică că facilitatea de keepalive trebuie activată icircn mod explicit

3 Studii de caz

Subsections

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

1 Fragmentarea pachetelor UDP

Deoarece UDP-ul este un serviciu fără conexiune toate datele pe care le primeşte de la nivelul

superior sunt icircncapsulate icircntr-o singură datagramă UDP care apoi va forma un pachet IP Dacă

pachetul IP astfel obţinut este prea mare atunci mecanismele IP de fragmentare icircl vor sparge icircn

bucăţi Exemplul următor icircncearcă să studieze exact acest fenomen

Pe maşina athos rulează un server de UDP pe portul 50007 Pe o altă maşină frodo aflată icircn

reţeaua locală este rulat un client care poate fi configurat să trimită un pachet UDP de o anumită

lungime Pentru a putea observa ce se icircntacircmplă pe athos este rulat tcpdump

Deoarece MTU-ul pentru o reţea Ethernet este icircn general 1500 şi antetul IP plus cel UDP ocupă

20 + 8 = 28 octeţi o datagramă UDP de dimensiune 1472 ar trebui sa fie trimisă nefragmentată

Pentru siguranţă folosind clientul de pe athos s-a trimis mai icircntacirci o datagramă UDP cu 1471

octeţi de date şi apoi icircncă una cu 1472 Pentru ambele tcpdump a indicat trimiterea lor fără

fragmentare

182556721144 frodonoi33274 gt athosnoi50007 udp 1471 (DF) (ttl 64 id

51481 len 1499)

182559846764 frodonoi33274 gt athosnoi50007 udp 1472 (DF) (ttl 64 id

51793 len 1500)

La o dimensiune de 1473 ar trebui ca trimiterea să genereze două pachete IP unul care să

conţină primii antetul UDP plus primii 1472 octeţi de date şi icircncă un pachet IP care conţine un

singur octet Iată ce indică tcpdump-ul

182605705813 frodonoi gt athosnoi udp (frag 3627411480) (ttl 64 len

21)

182605706116 frodonoi33274 gt athosnoi50007 udp 1473 (frag

3627414800+) (ttl 64 len 1500)

Intr-adevăr au fost generate două pachete IP

primul conţine doar un singur octet de date şi reprezintă ultimul fragment (bitul de more

fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest

lucru) care a fost spartă icircn bucăţi deplasamentul octetului primit in datagrama originală

este 1480

al doilea pachet este primul fragment din datagrama UDP şi conţine antetul UDP (din

cauza asta datele efective ocupă doar 1480 octeţi) deplasamentul este 0 şi bitul de more

fragments este setat (acest lucru este indicat de semnul ``+ de după deplasament)

După cum se poate observa ambele pachete poartă acelaşi număr de identificare (36274) Acest

lucru icircmpreună cu informaţiile date de flag-ul more fragments permite reconstrucţia la

destinaţie a datagramei UDP originale O problemă a acestui mod de fragmentare e că icircn cazul

pierderii unui fragment icircntreaga datagramă va fi compromisă şi va trebui retrimisă icircn icircntregime

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 6: udp tcp

telefonie clasică cineva formează un număr şi abia icircn momentul icircn care cealaltă persoană

răspunde se poate icircncepe conversaţia Fiind o conexiune host-la-host nu există noţiunile de

broadcast sau multicast

Transferul sigur de date este asigurat icircn următorul mod

Datele sunt icircmpărţite icircn bucăţi a căror dimensiune optimă e determinată de TCP spre

deosebire de UDP care trimite datagrame UDP corespunzătoare cu dimensiunea datelor

primite de la nivelul aplicaţie Unitatea de date trimisă de TCP către nivelul reţea poartă

numele de segment

Cacircnd TCP trimite un segment porneşte un timer şi dacă nu se primeşte confirmarea

segmentului respectiv icircntr-un anumit timp icircl retransmite

Icircn momentul icircn care se primeşte un segment TCP trimite o confirmare (din motive de

eficienţă aceasta poate fi amacircnată un anumit interval de timp)

Icircn headerul TCP este menţinută o sumă de control pentru detectarea modificărilor icircn date

Dacă se recepţionează un segment corupt TCP icircl ignoră urmacircnd să fie retransmis datorită

neprimirii confirmării

Deoarece segmentele TCP sunt transmise mai departe icircncapsulate icircn datagrame IP iar

acestea pot ajunge icircn orice ordine segmentele TCP pot ajunge icircn altă ordine decacirct cea icircn

care au fost trimise De aceea la destinaţie TCP-ul trebuie să se folosească de numere de

secvenţă pentru a reordona eventual segmentele icircnainte de a le livra către nivelul

aplicaţie De asemenea TCP trebuie să asigure ignorarea duplicatelor

TCP asigură controlul fluxului icircn condiţiile icircn care viteza de trimitere a datelor de la sursă

poate fi mult prea mare decacirct capacitatea de prelucrare de la destinaţie

Serviciul oferit de TCP este de tip flux de octeţi deoarece oferă garanţii că fluxul de date trimis

de sursă va fi livrat fără modificări la destinaţie Comparativ UDP-ul produce pentru fiecare

transfer cerut de nivelul aplicaţie un pachet IP (care ulterior poate fi supus fragmentării) care

dacă ajunge la destinaţie corect va fi livrat direct nivelului aplicaţie fără a garanta icircn vreun fel

ordinea

2 Formatul pachetelor TCP

Pachetele de date transmise de TCP segmentele sunt formate dintr-un antet (figura 72) de 20

octeţi urmat de datele primite de la nivelul aplicaţie Antetul poate uneori conţine şi o serie de

opţiuni caz icircn care poate ajunge la 60 octeţi

Figura 72 Structura unui segment TCP

Antetul unui segment TCP cuprinde

port sursă - 16 biţi pentru specificarea portului aplicaţiei transmiţătoare

port destinaţie - 16 biţi pentru specificarea portului aplicaţiei ce recepţionează segmentul

TCP

Aceste două porturi icircmpreună cu adresele ale sursei şi destinaţiei conţinute icircn antet-ul IP

identifică icircn mod unic conexiunea Pentru o pereche formată dintr-o adresă IP şi un port

se foloseşte adesea denumirea de socket (denumire introdusă icircn specificaţiile iniţiale ale

protocolului TCP icircn RFC 793)

număr de secvenţă - 32 biţi

Pentru a asigura un serviciu de tip flux de octeţi TCP numerotează fiecare octet de date

utilizacircnd un număr de secvenţă Numărul de secvenţă din cadrul antetului TCP specifică

destinaţiei care este primul octet din fluxul trimis La iniţierea unei conexiuni se setează

flag-ul SYN şi se alege aleator un număr de secvenţă de icircnceput utilizacircnd un generator de

numere de secvenţă ISN (Initial sequence number) Numărul de secvenţă al primului

octet de date va fi numărul generat ISN plus 1 deoarece pachetul de iniţiere (cu SYN

setat) consumă şi el un număr de secvenţă Se va vedea mai departe că şi flag-ul de

terminare a conexiunii FIN consumă şi el un număr de secvenţă

confirmare - 32 biţi

Reprezintă numărul de secvenţă al octetului de date pe care transmiţătorul confirmării se

aşteaptă să-l primească Astfel dacă s-a recepţionat octetul cu numărul de secvenţă x (icircn

numerotaţia sursei) pachetul de confirmare va avea flag-ul ACK setat şi va conţine

numărul de confirmare x + 1 Trimiterea unui ACK nu consumă un număr de secvenţă

deoarece atacirct acest cacircmp cacirct şi flag-ul ACK fac parte din antet şi după stabilirea

conexiunii ambele cacircmpuri devin active Acest mecanism nu permite confirmări selective

pentru că numărul de secvenţă specifică pacircnă unde s-au recepţionat date De exemplu

dacă la destinaţie au ajuns octeţii 1-1024 şi următorul segment primit conţine octeţii

2049-3072 nu se poate trimite confirmare pentru cel de-al doilea segment deci

confirmarea va cuprinde numărul de secvenţă 1025

lungimea antetului - 4 biţi

Specifică dimensiunea antetului ca număr de cuvinte de 32 de biţi (4 octeţi) Antetul

poate avea icircntre 20 şi 60 de octeţi deci valoarea acestui cacircmp va fi icircntre 5 (5 x 4 = 20

octeţi) şi 15 (15 x 4 = 60)

6 biţi rezervaţi pentru utilizări viitoare

6 biţi de control reprezentacircnd următoarele flag-uri ce pot fi setate simultan

o URG - cacircmpul urgent pointer este valid

o ACK - cacircmpul de confirmare este valid

o PSH - destinaţia trebuie să trimită datele către nivelul aplicaţie cacirct mai devreme

o RST - se doreşte resetarea conexiunii

o SYN - iniţierea conexiunii

o FIN - icircnchiderea conexiunii

dimensiunea ferestrei - 16 biţi

Reprezintă numărul de octeţi (icircncepacircnd cu numărul de secvenţă conţinut icircn cacircmpul de

confirmare) pe care destinaţia e dispusă să-l primească Este limitat la 65535 octeţi dar

cu toate că pare o limită destul de mare există situaţii cacircnd se doresc valori mult mai

mari Icircn acest scop se folosesc nişte opţiuni speciale descrise ceva mai tacircrziu care permit

scalarea ferestrei

suma de control - 16 biţi

Această sumă de control acoperă icircntregul segment TCP (atacirct datele cacirct şi antetul TCP) şi

spre deosebire de UDP este obligatoriu să fie completat de transmiţător şi verificat de

receptor Dar ca şi icircn cazul UDP-ului la calculul sumei de control se ia in considerare şi

o zona specială de 12 octeţi ce cuprinde pentru re-verificare cacircmpuri din antetul IP

(adresa IP a sursei şi a destinaţiei)[aici tre sa vina o referire la poza cu pseudo-antetu]

După adăugarea acestui pseudo-antet datele se icircmpart icircn cuvinte de 16 biţi icircn vederea

calculării sumei de control adăugacircndu-se eventual şi un octet de aliniere

urgent pointer - 16 biţi

Este utilizat pentru specificarea deplasamentului ultimului octet de date trimis icircn regim

urgent Astfel ultimul octet din secvenţa urgentă se obţine adunacircnd acest cacircmp la

numărul de secvenţă Ce icircnseamnă acest mod urgent de transmitere există situaţii icircn care

aplicaţiile vor să trimită date `neordonate` Să presupunem că aplicaţia a trimis către

nivelul transport o cantitate mare de date dar la un moment dat observă ceva icircn neregulă

şi doreşte să anuleze operaţia Dacă trimite o comandă de anulare aceasta va fi adăugată

la sfacircrşitul şirului de octeţi deci nu se va putea icircmpiedica ajungerea acestora la nivelul

aplicaţie de la receptor Activacircnd modul urgent datele urgente (comanda de anulare) vor

fi plasate la icircnceputul pachetului Aplicaţiile mai cunoscute care folosesc acest mod sunt

Telnet Rlogin şi FTP

opţiuni - pacircnă la 40 de octeţi (figura 73)

Cele mai utilizate opţiuni sunt

o Sfacircrşit de opţiuni (end of option) - 1 octet

Este utilizat pentru alinierea datelor conţinute icircn cacircmpul de opţiuni Nu poate fi

utilizat decacirct o singură dată marcacircndu-se astfel sfacircrşitul opţiunilor şi icircnceperea

datelor efective Dacă pentru alinierea la un cuvacircnt de 32 de biţi e nevoie de mai

mult de 1 byte se va utiliza opţiunea no operation Orice apare după această

opţiune pacircnă la icircnceputul cuvacircntului următor de 32 de biţi e ignorat

o no operation - 1 octet

Utilizat pentru alinierea la cuvinte de 32 de biţi

o Dimensiunea maximă a segmentului (Maximum Segment Size (MSS)) - 16 biţi

Icircn ciuda denumirii defineşte lungimea maximă a datelor nu dimensiunea

icircntregului segment Poate lua valori icircntre 0 şi 65535 valoarea implicită fiind 536

Această opţiune e valabilă doar icircn pachetele de iniţiere a conexiunii (cele cu flag-

ul SYN setat) fiecare parte făcacircnd cunoscută dimensiunea maximă a datelor

dispusă să le primească icircntr-un pachet Icircn principiu cu cacirct această valoarea e mai

mare e mai bine (deoarece se recuperează din spaţiul ocupat de antetele TCP şi

IP) pacircnă cacircnd apare fragmentarea Valoarea maximă la care se poate seta este

MTU (Maximum Transfer Unit) minus dimensiunea antetului IP şi TCP (1460

octeţi icircn cazul Ethernet)

o Factor de scalare a ferestrei (Window scale factor) - 1 octet

Pentru situaţiile icircn care se doreşte utilizarea unei ferestre mai mare de 65535 bytes

se poate utiliza acest cacircmp pentru mărirea dimensiunii ferestrei Noua dimensiune

va fi Chiar dacă

factorul de scalare poate fi maxim 255 icircn cazul TCPIP el nu poate depăşi

valoarea 16 deoarece dimensiunea maximă a ferestrei nu poate fi mai mare decacirct

valoarea celui mai mare număr de secvenţă ( )

Acest factor se poate seta doar la iniţierea conexiunii Icircn timpul transferului de

date se poate modifica dimensiunea ferestrei dar factorul de scalare rămacircne

acelaşi Dacă cel care a iniţiat conexiunea a trimis icircn segmentul de iniţiere şi acest

factor dar icircn pachetul cu ACK destinatarul nu şi-a trimis şi el factorul atunci se la

considera 0 icircn ambele direcţii Invers dacă cel care solicită deschiderea

conexiunii nu setează factorul destinaţia nu va putea seta factorul de scalare

o Timestamp - 10 octeţi

Utilizat pentru reţinerea timpului icircn vederea calculării RTT (Round Trip Time)

Cacircmpul timestamp e completat de sursă icircn momentul trimiterii segmentului La

destinaţie valoarea este reţinută şi copiată icircn cacircmpul timestamp echo reply al

pachetului cu confirmarea RTT-ul este calculat de sursă făcacircnd diferenţa dintre

timpul curent şi această valoare

Figura Opţiuni TCP

3 Iniţierea şi terminarea unei conexiuni TCP

TCP este un protocol orientat conexiune deci presupune stabilirea unei căi virtuale icircntre sursă şi

destinaţie

Subsections

Protocolul de iniţiere

o 1 Deschiderea simultană

Protocolul de terminare

o 2 Terminarea simultană

o 3 Resetarea conexiunii

Diagrama de stări

Protocolul de iniţiere

Modul de transmisie icircn cazul protocolului TCP este full-duplex deci sunt transmise date

simultan icircn ambele direcţii Aceasta presupune că cel care iniţiază conexiunea trebuie să

primească aprobarea celuilalt capăt icircnainte de icircnceperea transferului de date sursa icircşi anunţă

intenţia de a iniţia o conexiune destinaţia trimite un pachet cu confirmarea cererii şi un pachet de

iniţiere a conexiunii de la el la sursă iar apoi sursa confirmă cererea primită de la destinaţie Paşii

2 şi 3 pot fi realizaţi prin trimiterea unui singur pachet de aceea protocolul de iniţiere este

cunoscut sub numele de three-way handshake

Icircn cadrul protocolului de iniţiere există 2 tipuri de cereri de iniţiere cerere activă (active open)

iniţiată de clientul ce doreşte să stabilească conexiunea cu serverul şi cerere pasivă (passive

open) din partea serverului

Cei 3 paşi sunt

1 Clientul trimite un segment cu flag-ul SYN setat şi care conţine portul sursă portul de la

destinaţie şi numărul de secvenţă generat iniţial (ISN) de la care se vor numerota octeţii

de la client către server Opţional se pot stabili parametrii conexiunii prin setarea lungimii

maxime a segmentelor (MSS) dispus să le primească de la server factorului de scalare a

ferestrei Acest prim segment nu conţine nici un parametru de confirmare şi de asemenea

nu are rost să conţine să seteze dimensiunea ferestrei

2 Al doilea segment e trimis de server şi are un rol dublu confirmă segmentul primit de la

client prin setarea flag-ului ACK şi completează numărul de secvenţă cu numărul de

secvenţă primit plus 1 şi al doilea rol iniţializează conexiunea de la el către client prin

setarea flag-ului SYN şi generarea unui număr de secvenţă iniţial ce va fi folosit icircn

numerotarea octeţilor de la server spre client Pe lacircngă aceasta trebuie să conţină

dimensiunea ferestrei şi opţional poate seta factorul de scalare şi dimensiunea maximă a

segmentului acceptat

3 Clientul trimite un segment cu confirmarea cererii din partea serverului (ACK setat +

completează numărul confirmat cu numărul de secvenţa primit + 1) Ca şi icircn cazul

pasului 2 trebuie să seteze dimensiunea ferestrei Acest pachet poate conţine date

Subsections

1 Deschiderea simultană

1 Deschiderea simultană

Se poate icircntacircmpla ca uneori cele două capete care vor să comunice să icircncerce să stabilească

conexiunea simultan Icircn acest caz după ce fiecare a trimis segmentul de iniţiere (iniţiere activă)

ambele vor trimite un segment cu SYN + ACK şi se va stabili o singură conexiune nu două

Protocolul de terminare

Oricare dintre cele două părţi poate solicita icircnchiderea conexiunii dar conexiunea fiind full-

duplex transferul de date icircn celălalt sens poate continua (această situaţie e denumită half-close)

O icircnchidere completă a unei conexiuni TCP presupune următorii paşi

1 Clientul trimite un segment cu flag-ul FIN activat solicitacircnd icircnchiderea conexiunii

2 Serverul trimite un segment ACK confirmacircnd primirea cererea Numărul de confirmare

se completează normal ca numărul de secvenţă primit + 1

3 Serverul continuă să trimită date către client şi cacircnd doreşte să icircnchidă şi el conexiunea

trimite un segment cu FIN activat

4 Clientul trimite un pachet ACK confirmacircnd icircnchiderea conexiunii

Cel care iniţiază primul procedura de icircnchidere (trimite primul FIN) realizează o icircnchidere activă

(active close) iar celălalt capăt o icircnchidere pasivă (passive close) Icircn mod normal cel care

realizează iniţierea activă va fi primul ce va trimite FIN dar oricare dintre cei doi poate icircnchide

activ conexiunea

Subsections

2 Terminarea simultană

3 Resetarea conexiunii

2 Terminarea simultană

Icircn mod similar cu deschiderea simultană există posibilitatea ca ambele capete ale conexiunii TCP

să iniţieze simultan procedura de icircnchidere a conexiunii Icircn acest caz ambele părţi vor trimite

FIN şi vor aştepta primirea unui ACK Icircn continuare fiecare va primi cererea de terminare şi va

trimite ACK Se observă că numărul de segmente transferate pentru realizarea icircnchiderii

conexiunii (4 segmente) este acelaşi ca la terminarea normală

3 Resetarea conexiunii

Există situaţii icircn care TCP doreşte resetarea conexiunii De exemplu dacă se solicită iniţierea

unei conexiuni la un port inexistent Icircn acest caz cealaltă parte va trimite un segment cu bitul

RST setat pentru a anula solicitarea O altă situaţie este atunci cacircnd se constată că celalalt capăt

al conexiunii nu răspunde un anumit timp (timeout)

Diagrama de stări

Toate evenimentele ce au loc icircn timpul stabilirii conexiunii transferului şi icircnchiderii conexiunii

pot fi rezumate printr-un automat finit cunoscut sub numele de diagrama de stări După cum

chiar numele sugerează este o maşină cu un număr limitat de stări O stare este păstrată pacircnă icircn

momentul apariţiei unui eveniment moment icircn care se poate trece icircn altă stare şisau efectua o

acţiune

Aceste stări posibile sunt (denumirile sunt asemănătoare cu cele utilizate de netstat) cele din

tabelul 71

Tabela Stările diagramei de stări TCP

Stare Descriere

CLOSED Nu există conexiune

LISTEN Serverul aşteaptă cereri de la clienţi

SYN_SENT Cerere de iniţiere (activă) a conexiunii Se

aşteaptă confirmarea

SYN_RCVD S-a primit o cerere de iniţiere conexiune

ESTABLISHED S-a stabilit conexiunea

FIN_WAIT_1 Aplicaţia a solicitat icircnchiderea conexiunii

FIN_WAIT_2 Serverul a acceptat icircnchiderea conexiunii

CLOSING Ambele părţi solicită simultan icircnchiderea

conexiunii

TIME_WAIT Conexiune icircnchisă dar se aşteaptă ca

pachetele retransmise să dispară

CLOSE_WAIT Serverul aşteaptă icircnchiderea dinspre partea

aplicaţiei

LAST_ACK Serverul a icircnchis conexiunea Aşteaptă

ultima confirmare

Icircn diagrama ilustrată icircn figura 74 putem observa 3 tipuri de tranziţii icircntre cele 11 stări tranziţii

ce corespund unei funcţionări normale pentru client (linii normale continue) pentru server (linii

normale icircntrerupte) şi tranziţii pentru situaţii nestandard (linii subţiri continue)

O comportarea normală pentru client presupune parcurgerea următoarelor stări CLOSED

SYN_SEND ESTABLISHED FIN_WAY_1 FIN_WAY_2 TIME_WAIT

Iniţial clientul TCP se află icircn starea CLOSED

Aşteptacircnd icircn starea CLOSED clientul poate primi de la aplicaţie o cerere de iniţiere

activă a unei conexiuni Trimite un segment SYN şi trece icircn starea SYN_SENT

Icircn starea SYN_SENT clientul aşteaptă de la server un segment ACK+SYN după care

trimite un ACK şi trece icircn starea ESTABLISHED Din acest moment poate icircncepe

transferul efectiv de date Clientul va rămacircne icircn această stare cacirct timp are de trimisprimit

date

Aflat icircn această stare clientul TCP poate primi din partea aplicaţiei o cerere de icircnchidere a

conexiunii Icircn acest caz va trimit un segment FIN şi trece icircn starea FIN_WAIT_1

Icircn această stare clientul aşteaptă ACK din partea serverului După ce-l primeşte

conexiunea icircntr-un sens se va icircnchide şi clientul trece icircn starea FIN_WAIT_2

Starea FIN_WAIT_2 durează pacircnă cacircnd primeşte cererea de icircnchidere a conexiunii FIN

din partea serverului Trimite ACK şi va trece icircn starea TIME_WAIT

Icircn această stare se va porni un timer cu valoarea setată la dublul timpului de viaţă estimat

pentru un segment de lungime maximă MSL (Maximum Segment Lifetime) Acest timer

permite retransmiterea ACK-ului icircn cazul icircn care acesta se pierde (celălalt capăt va da

timeout şi va retransmite segmentul FIN) Icircn tot acest time cei doi sockeţi (de la client şi

server) nu vor putea fi reutilizaţi Totodată pachetele icircntacircrziate care sosesc icircn această

perioadă sunt ignorate După expirarea acestui timer clientul revine icircn starea iniţială

CLOSED

Din punctul de vedere al unui server o comportare standard parcurge următoarele stări

CLOSED LISTEN SYN_RCVD ESTABLISHED CLOSE_WAIT şi LAST_ACK

Iniţial serverul TCP se află icircn starea CLOSED

Icircn această stare poate primi de la aplicaţia server o cerere de iniţiere activă şi trece icircn

starea LISTEN

Aflat icircn starea LISTEN serverului TCP poate recepţiona un segment SYN de la un client

TCP Icircn acest caz va trimite ACK+SYN şi va trece icircn starea SYN_RCVD

Icircn această stare serverul aşteaptă primirea confirmării de la client moment icircn care

conexiunea e stabilită icircn ambele sensuri şi se poate icircncepe transferul de date (starea

ESTABLISHED)

Clientul TCP poate solicita icircnchiderea conexiunii trimiţacircnd un segment FIN către server

Icircn acest caz serverul TCP trimite confirmarea şi trece icircn starea CLOSE_WAIT

Icircn această stare serverul aşteaptă să primească din partea programului server icircnchiderea

conexiunii moment icircn care va trimite către client un segment FIN şi trece icircn starea

LAST_ACK

Serverul aşteaptă primirea ultimei confirmări de la client după care revine icircn starea

CLOSED

Atacirct serverul cacirct şi clientul TCP se pot afla icircn oricare din cele 11 stări ale diagramei

Figura Diagrama de stări pentru TCP

4 Controlul fluxului

Dacă icircncă de la icircnceput s-a reuşit stabilirea formatului unui pachet TCP şi a modulului icircn care

trebuie să se facă icircnchiderea şi deschiderea unei conexiuni nu acelaşi lucru se poate spune şi

despre modul icircn care ar trebui să se realizeze controlul fluxului Ţinacircnd seama icircnsă că din 1989

(de cacircnd datează RFC-ul 2581 cel despre care am menţionat că specifică icircn mod clar modul icircn

care trebuie să se comporte o implementare de TCP) TCP-ul a rămas neschimbat putem să icircl

considerăm un rezultat important al domeniului reţelor de calculatoare

Icircn cele ce urmează vom icircnţelege prin controlul fluxului totalitatea algoritmilor care permit

atingerea unei viteze de transfer punct-la-punct cacirct mai mare pentru toate conexiunile existente

Icircn principal aceşti algoritmi stabilesc modul icircn care segmentele şi confirmările trebuie trimise şi

ce acţiuni trebuie executate icircn situaţiile icircn care răspunsurile aşteptate de la celălalt capăt icircntacircrzie

să vină

Subsections

Icircntacircrzierea confirmărilor

Algoritmul Nagle

Fereastra glisantă

Slow start

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Evitarea congestiei

Fast Retransmission Fast Recovery

Sindromul ``Silly Window

TCP Keepalive Timer

Icircntacircrzierea confirmărilor

O modalitate simplă de generare a confirmărilor este de a trimite cacircte una pentru fiecare segment

primit Această politică prezintă avantajul de a face comunicaţia self-clocking icircnsă este

ineficientă dacă segmentele care nu conţin decacirct confirmări sunt urmate la scurtă distanţă (cacircteva

zeci de milisecunde) de segmente ce conţin date efective Pentru a evita această situaţie se

procedează2 la icircntacircrzierea (200ms este o valoare uzuală icircn RFC 1122 se specifică o valoare

maximă de 500ms) a segmentelor care conţin doar confirmări Această strategie face posibil ca

un răspuns generat de primirea unor date să plece sper celălalt capăt icircn acelaşi segment cu

confirmarea

Observaţie deoarece este dificil de menţinut timere pentru fiecare confirmare diferenţa de

200ms este calculată de un timer global Din acest motiv modul efectiv de comportare poate fi

descris şi icircn felul următor cacircnd un segment nu conţine decacirct o confirmare el este pus icircntr-o

coadă ce va fi inspectată de un proces care din 200 icircn 200 ms trimite tot ce s-a acumulat icircn

coada

Footnotes

2

Acest comportament a fost propus de David D Clark icircn iulie 1982 icircn RFC 813

Algoritmul Nagle

Acest algoritm3 icircncearcă să icircmbunătăţească performanţele exploatacircnd următoarea caracteristică

foarte des icircntacirclnită icircn dialogul dintre două staţii dacă se icircncearcă trimiterea unor date de

dimensiune mică icircnsă există icircncă date neconfirmate de partener atunci ele sunt buffer-ate şi

trimise icircntr-un segment mai mare cacircnd soseşte confirmarea aşteptată Icircn acest fel se poate evita

generarea datagramelor mici (tinygrame) icircn situaţia unei legături lente Icircn cazul unei legături

rapide confirmările vor veni repede şi icircntacircrzierea introdusă de algoritm va neglijabilă

Există icircnsă şi cazuri icircn care acest algoritm duce la deprecierea performanţelor mesajele scurte

generate de mişcările mouse-ului icircn cazul folosirii unui server X Window sau utilizarea tastelor

care trimit mai mult de un caracter (secvenţe escape) Pentru a rezolva aceste inconveninte API-

ul de utilizare a TCP-ului trebuie să ofere o modalitate de a dezactiva acest algoritm (icircn sistemele

bazate pe sockeţi există icircn acest scop opţiunea TCP_NODELAY)

Footnotes

algoritm3

Algoritmul aparţinacircnd lui John Nagle a fost propus icircn ianuarie 1984 icircn RFC 896

Fereastra glisantă

Algoritmul implementat de TCP pentru a implementa transferul sigur de date este cunoscut icircn

teorie sub numele de Go-Back-N Icircn acest algoritm se utilizează numere de secvenţă pentru a

distinge pachetele icircntre ele şi o coadă (dimensiunea maximă a cozii reprezintă fereastra) de

pachetele a căror confirmare se aşteaptă Pachetele se icircmpart icircn 4 categorii

1 pachete trimis şi pentru care s-a primit confirmare

2 pachete trimise şi pentru care se aşteaptă icircncă confirmarea

3 pachete care nu au fost trimise icircncă dar care nu depăşesc limitele ferestrei şi deci pot fi

trimise

4 pachete care icircncă nu au fost trimite şi care nici nu vor putea fi trimise decacirct după ce au

fost trimise toate pachetele din categoria 3 şi s-au primit o parte din confirmările la

pachetele din categoria 2

Dacă confirmările pentru pachetele din categoria 2 icircntacircrzie prea mult (un mecanism de timer-e

informează asupra acestui lucru) atunci ele vor fi retrimise Icircn versiunea iniţială TCP-ul nu

permitea decacirct confirmări pozitive ceea ce icircnseamnă că avansarea ferestrei se va icircmpotmoli la

segmentele neconfirmate Cum se poate evita aceasta situaţie vom discuta icircn detaliu icircn capitolele

următoare O soluţie foarte radicală o constituie introducerea de confirmări selective (acest lucru

este realizat de RFC 2018 din octombrie 1996) Această modifică face ca TCP-ul actual să fie un

hibrid de Go-Back-N şi Selective Repeat

Deoarece dimensiunea ferestrei este anunţată la fiecare segment un client lent poate ca pe măsură

ce trimite confirmările să informeze despre progresul icircnregistrat la livrarea datelor următorului

nivel (aplicaţie) Dacă datele vin prea repede pentru viteza cu care clientul procesează datele

fereastra fereastra se va dimiua şi chiar icircnchide (acest lucru se realizează anunţacircnd o fereastră de

dimensiune zero) Cum se realizează efectiv redeschiderea vom analiza icircntr-un capitol viitor

Slow start

Un transfer de date TCP poate să icircnceapă prin transmiterea de segmente pacircnă la umplerea

icircntregii ferestre după care fie se primesc confirmări care vor permite unor noi pachete să fie

trimise fie vor expira timer-ele de retransmisie şi se va icircncepe retrimiterea pachetelor de la

icircnceputul ferestrei Din păcate un astfel de comportament poate duce la pomparea icircn reţea a unui

număr de pachete prea mare pentru capacitatea disponibilă efectiv icircnrăutăţind congestia Pentru

a evita acest lucru s-a propus următoarea soluţie4 iniţial se trimite un segment după primirea

confirmării lui se trimit două segmente după sosirea confirmărilor pentru ele se trimit patru

segmente şi aşa mai departe La un moment dat fie vor icircncepe să se piardă segmente (un indiciu

că s-a atins capacitatea maximă a canalului) fie se va umple fereastra pe care o anunţă cel care

primeşte Trebuie să remarcam că datorită creşterii exponenţiale a numărului de segmente se va

atinge destul de repede una din cele două situaţii

Modalitatea efectivă de implementare a acestui algoritm are la bază utilizarea unei ferestre de

congestie (congestion window cwnd) care este iniţializată cu dimensiunea unui segment (cwnd

se calculează icircn octeţi) şi la fiecare pas este dublată fereastra efectivă din cadrul căreia se pot

trimite segmente este dată de minimul dintre ultima fereastra comunicată de partener şi cwnd

Footnotes

soluţie4

Soluţia aparţine lui V Jacobson şi a fost prezentată icircn 1988 la conferinţă ACM

SIGCOMM-88

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Deoarece TCP trebuie să funcţioneze icircn condiţii variate de latenţă modul icircn care se face

retransmiterea trebuie să fie cacirct mai flexibil (şi simplu icircn acelaşi timp pentru a introduce un

overhead cacirct mai mic) Timpul cacirct se aşteaptă venirea unei confirmări (retransmission timeout

RTO) este calculat prin cronometrarea timpului care icirci ia unui segment trimis să fie confirmat

Pentru o anumită conexiune se cronometrează cacircte un singur segment la un moment dat iar pe

baza RTT-ului măsurat se actualizează valoare RTO-ului

Icircn RFC 793 formula de calcul a RTO-ului este următoarea

unde este ultimul RTT măsurat este o estimare ponderată pentru RTT este un coeficient

de ponderare care icircn general are valoarea iar este un coeficient cu o valoare recomandată

de După cum se poate observa icircn valoarea lui este inclusă icircn mare măsură vechea valoarea

Icircn acest fel ajustarea RTT-ului se face treptat Din păcate acest mod de calcul nu funcţionează

bine la variaţii mari ale RTT-ului ducacircnd la creşterea numărului de retransmisii exact atunci

cacircnd fenomenul de congestie icircncepe să apară

Pentru a remedia aceste neajunsuri V Jacobsen a propus icircn 1988 o nouă metodă de calcul o

metodă care ţine seama seamă şi de modul icircn care variază diferenţa dintre RTT-uri Formulele

folosite sunt următoarele

unde este un estimare pentru media RTT-urilor este o estimare pentru abaterea RTT-urilor

faţă de medie (o aproximaţie suficientă pentru abaterea pătratică medie care icircnsă este mult mai

costisitor de calculat) este diferenţa dintre RTT-ul măsurat ( ) şi estimarea curentă ( )

Coeficientul cu care este actualizată estimarea curentă are valoarea de iar cel cu care este

actualizat estimarea abaterii este La stabilirea unei conexiuni valorile pentru şi sunt

alese astfel icircncacirct să rezulte un RTT de secunde şi un de 3 secunde (aceste recomandări

sunt făcute de RFC 1122)

Dacă pentru un anumit segment nu se primeşte confirmarea icircn intervalul indicat de el va fi

retrimis şi noul este dublat Valoarea maximă admisă pentru este de 240 secunde

Deoarece icircn cazul retrimiterilor nu se poate determina cu exactitate căruia din segmentele trimise

aparţine confirmarea actualizarea estimărilor este amacircnată pacircnă cacircnd se reuşeşte trimiterea

corectă (s-a primit confirmare) fără retransmitere(``din prima) a unui segment Acest artificiu

(deloc neimportant) care permite evitarea actualizarea eronată a estimărilor este cunoscut sub

numele de algoritmul lui Karn şi a fost propus icircn 1987 de P Karn şi C Partridge

Evitarea congestiei

Dacă cei doi parteneri care comunică prelucrează datele suficient de repede şi vor să transfere un

volum mare de date atunci limitarea de care se vor lovi este cea dată de viteza reţelei Din cauza

modului ``best-effort pe care IP-ul icircl oferă cacircnd canalul de comunicaţie este saturat o parte din

segmentele TCP se vor pierde Icircn mod poate paradoxal atacirct transmiţătorului cacirct şi receptorul se

pot afla icircn poziţia de a fi primii icircn detectarea pierderii unui segment Unul din indiciile de la

transmiţător care semnalează pierderea unui segment este (icircn mod evident) apariţia 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 icircn varianta iniţială nu

permite decacirct confirmări pozitive singurul lucru pe care receptorul icircl poate face este ca la fiecare

segment out-of-order primit să trimită o confirmare indicacircnd prin aceasta că la el continuă să

vină segmente icircnsă cel indicat de numărul de secvenţă de confirmare lipseşte Primirea acestor

confirmări multiple este al doilea mod icircn care transmiţătorul poate afla de apariţia congestiei

Algoritmul ce trebuie aplicat icircn momentul icircn care se detectează apariţia congestiei este cunoscut

sub numele de ``evitarea congestiei (congestion avoidence) Principiul care stă la baza lui este

ca la apariţia congestiei fie să se treacă la o incrementare liniară a dimensiunii ferestrei dacă

congestia a fost detectată ca urmare a primirii unor confirmări identice repetate fie să se reia

slow start-ul icircn cazul icircn care congestia s-a detectat prin expirarea unui timer de timeout

Implementarea acestui algoritm se bazează pe utilizarea unui nou contor (sstresh) care să indice

dimensiunea ferestrei de la care se trece de la incrementarea exponenţială la cea liniară

Algoritmul efectiv este următorul

1 la stabilirea unei noi conexiuni se pleacă cu sstresh iniţializat la valoare de 64K şi cwnd

la dimensiunea unui segment

2 trimiterea de segmente se face fără a depăşi minimul dintre fereastra publicată de partener

(pentru a nu depăşi capacitatea de procesesare a partenerului) şi cwnd-ul curent (pentru a

nu depăşi limita impusă de capacitatea reţelei)

3 la apariţia congestiei sstresh este setat la jumătatea valorii ferestrei curente (minimul

dintre fereastra anunţată de partener şi cwnd icircnsă cel puţin dimensiunea corespunzătoare

pentru două segmente) dacă congestia a fost detectată prin expirarea unui timer de

timeout atunci cwnd este iniţializat cu dimensiunea unui segment

4 la primirea unei confirmări incrementarea se face icircn două moduri icircn funcţie de relaţie icircn

care se află cwnd şi sstresh

1 dacă cwnd e mai mic sau egal cu sstresh se face incrementarea exponenţială

caracteristică slow start-ului (care de fapt nu e deloc slow icircn cazul de faţă)

2 dacă cwnd e mai mare ca sstresh atunci se face o incrementare cu dimensiunea

unui segment

Fast Retransmission Fast Recovery

După cum am văzut un receptor care primeşte segmente out-of-order va trimite transmiţătorului

confirmări duplicate Algoritmul denumit ``fast retransmission recomandă următoarele două

comportamenet

1 un receptor care detectează segmente out-of order trebuie să nu icircntacircrzie trimiterea de

confirmări (după cum am văzut icircn general confimările sunt icircntacircrziate micşora numărul de

pachete fără date care sunt transferate)

2 un transmiţător care care primeşte mai mult de trei confirmări duplicate trebuie să

retrimită segmentul indicat ca fiind neprimit de confirmările icircn cauză fără a aştepta

expirarea timer-ul de timeout

Algoritmul de ``fast recovery icircncearcă să optimizeze şi mai mult comportamentul

transmiţătorului care detectează un număr de trei sau mai multe confimări duplicate Mai exact el

recomandă trecerea la actualizarea liniară a ferestrei (congestion avoidance) Acest tip de

comportament se poate justifica prin următorul raţionament deoarece icircncă mai sunt transferate

date icircntre cei doi parteneri (şi acest lucru se icircntacircmplă sigur de vreme ce sosesc confirmări

duplicate icircn cazul acesta) icircnseamnă că transferul nu este afectat de o congestie severă şi prin

urmare trecerea la slow start nu e (icircncă) necesară (slow start-ul eliberează aproape complet

canalul deoarece cwnd este resetat la dimensiunea unui singur segment)

Cei doi algoritmi pot fi implementaţi icircn felul următor

1 cacircnd se detectează trei confirmări consecutive identice se setează sstresh la jumătate din

valoarea cwnd se retransmite segmentul care s-a pierdut şi se setează cwnd la valoarea

egală cu sstresh plus dimensiunea a trei segmente (acest lucru va face ca algoritmul de

incrementare a cwnd să treacă la incrementare liniară)

2 la fiecare confirmare duplicată care mai soseşte se incrementează cwnd se incrementează

cu dimensiunea unui segment

3 cacircnd icircncetează primirea de confirmări duplicate (segmentul retrimis a ajuns cu bine la

receptor şi s-a trimis o confirmare care acoperă segmentul care se pierduse iniţial) cwnd

este setat la valoarea sstresh

Sindromul ``Silly Window

Protocoalele bazate pe fereastră glisantă (cum este şi TCP-ul) pot să ajungă icircn situaţia deloc

fericită de trimite un număr mare de segmente mici icircn loc de segmente de dimensiune maximă

Acest tip de comportament este cunoscut sub numele de sindromul ``silly window

O modalitate prin care TCP-ul poate să cadă victimă acestui tip de comportament este

deschiderea de ferestre cu dimensiune foarte mică O altă situaţia nefericită este cea icircn care un

transmiţător este ``lacom şi trimite date indiferent de cacirct de mică este fereastra (după cum vom

vedea imediat uneori are sens şi un astfel de comportament) Algoritmul de evitare a acestor

neajunsuri este următorul

1 un receptor nu trebuie să anunţe deschideri de ferestre mici Mai exact nu se recomandă

anunţarea unei incrementări a ferestrei mai mică decacirct dimensiunea unui segment (MSS)

sau jumătate din buffer-ul aflat la dispoziţia receptorului oricare din ele e mai mică

2 un transmiţător va trimite date doar icircn următoarele cazuri

1 se poate trimite un segment icircntreg

2 se poate trimite jumătate din dimensiunea celei mai mari ferestre pe care

partenerul a publicat-o pacircnă acum

3 toate datele trimise pacircnă acum au fost confirmate sau algoritmul Nagle este

dezactivat şi se trimit toate datele care sunt icircn buffer-ul de trimitere

Cacircteva justificări cazul 2b tratează cazul icircn care partenerul anunţă ferestre mai mici decacirct

dimensiunea unui segment iar cazul 2c impune condiţiile respectării algoritmului Nagle după

cum se vede dacă algoritmul Nagle este activ şi s-au acumulat destul date mai exact cacirct

dimensiunea unui segment el va fi trimis chiar dacă există segmente neconfirmate Pentru

implementarea comportamentului impus de 2b un transmiţător trebuie să ţină evidenţa celei mai

mari ferestre pe care partenerul a anunţat-o Ţinacircnd seama că dimensiunea acestor buffer-e nu se

modifică acest mod de a icircncerca determinarea lor este suficient

O altă problemă legată tot de ferestre este cazul icircnchiderii acesteia Un mod icircn care s-ar putea

anunţa redeschiderea este trimiterea de către receptor a unei confirmări (duplicat) care să anunţe

redeschiderea la o anumită valoare a ferestrei Deoarece acest pachet nu trebuie confirmat icircn mod

special şi s-ar putea să se piardă se poate ajunge icircn situaţia icircn care receptorul a anunţat

redeschiderea ferestrei segmentul s-a pierdut iar transmiţătorul icircncă mai icircl mai aşteaptă pentru a

putea continua transferul Rezolvarea la această problemă s-a făcut prin impunerea unui alt

comportament

1 transmiţătorul va trimite segmente cu dimensiunea datelor de un octet prin care sondează

deschiderea ferestrei intervalul la care se sondează redeschiderea ferestrei se dublează

(exponenţial backoff) icircn RFC 793 dimensiunea maximă recomandată este de 2 minute

icircnsă icircn RFC 1122 se specifică că maximul este acelaşi cu cel din cazul retransmisiei (240

secunde)

2 receptorul trebuie să refuze aceste pachete răspunzacircnd cu segmente de confirmare care

indică neprimirea octetului respectiv

Observaţie timer-ul special necesar pentru implementare la transmiţător a comportamentului de mai sus este cunoscut sub numele de ``TCP Persistent Timer Numele este justificat de faptul că sondarea deschiderii se va face pacircnă cacircnd fie fereastra se deschide fie conexiunea se icircntrerupe TCP Keepalive Timer

Un lucru interesant despre TCP este faptul că dacă nivelele superioare nu comunică nimic icircntre

ele pentru o perioadă lungă 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 icircn care au trecut cu succes de faza stabilirii legăturii Dacă nivelurile

inferioare (reţeaIP fizic) devin temporar indisponibile cacirct tip cei doi nu vor să comunice atunci

acest lucru nu va perturba icircn nici un fel activitatea şi acest lucru este acceptabil Problemele

icircncep să apară icircn momentul icircn care cei doi doresc să comunice şi nivelele inferioare nu mai

permit acest lucru Evident că cel care va dori să comunice ceva va detecta icircntreruperea legăturii

şi va icircnchide conexiunea Ce se icircntacircmplă icircnsă dacă celălalt capăt nu are nimic de comunicat (de

exemplu este un server care oferă anumite servicii) Pentru el legătura va fi icircn continuare activă

şi icircn general anumite resurse vor fi rezervate pentru aceasta Rezolvarea acestei situaţii este dată

de introducerea unei mecanism de sondare a stării legăturii pe baza unui timer (TCP Keepalive

Timer) care se declanşează din două icircn două ore La fiecare expirare a timer-ului se trimite un

segment fără date care confirmă datele primite pacircnă atunci Răspunsul care trebuie primit este tot

un segment fără date care confirmă datele primite de partener (practic o re-publicare a stării celor

doi parteneri) Dacă răspunsul nu este primit timp de 75 secunde atunci segmentul va fi retrimis

Dacă după 10 astfel de icircncercări tot nu s-a primit nici un răspuns atunci conexiunea se va

considera terminată şi se va anunţa nivelul superior asupra acestui lucru

Observaţii

dacă o staţie primeşte segmente de keepalive despre conexiuni care nu mai sunt active

(de exemplu a fost resetat) atunci va răspunde cu segmente de reset (acesta e un procedeu

standard)

RFC 1122 specifică că facilitatea de keepalive trebuie activată icircn mod explicit

3 Studii de caz

Subsections

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

1 Fragmentarea pachetelor UDP

Deoarece UDP-ul este un serviciu fără conexiune toate datele pe care le primeşte de la nivelul

superior sunt icircncapsulate icircntr-o singură datagramă UDP care apoi va forma un pachet IP Dacă

pachetul IP astfel obţinut este prea mare atunci mecanismele IP de fragmentare icircl vor sparge icircn

bucăţi Exemplul următor icircncearcă să studieze exact acest fenomen

Pe maşina athos rulează un server de UDP pe portul 50007 Pe o altă maşină frodo aflată icircn

reţeaua locală este rulat un client care poate fi configurat să trimită un pachet UDP de o anumită

lungime Pentru a putea observa ce se icircntacircmplă pe athos este rulat tcpdump

Deoarece MTU-ul pentru o reţea Ethernet este icircn general 1500 şi antetul IP plus cel UDP ocupă

20 + 8 = 28 octeţi o datagramă UDP de dimensiune 1472 ar trebui sa fie trimisă nefragmentată

Pentru siguranţă folosind clientul de pe athos s-a trimis mai icircntacirci o datagramă UDP cu 1471

octeţi de date şi apoi icircncă una cu 1472 Pentru ambele tcpdump a indicat trimiterea lor fără

fragmentare

182556721144 frodonoi33274 gt athosnoi50007 udp 1471 (DF) (ttl 64 id

51481 len 1499)

182559846764 frodonoi33274 gt athosnoi50007 udp 1472 (DF) (ttl 64 id

51793 len 1500)

La o dimensiune de 1473 ar trebui ca trimiterea să genereze două pachete IP unul care să

conţină primii antetul UDP plus primii 1472 octeţi de date şi icircncă un pachet IP care conţine un

singur octet Iată ce indică tcpdump-ul

182605705813 frodonoi gt athosnoi udp (frag 3627411480) (ttl 64 len

21)

182605706116 frodonoi33274 gt athosnoi50007 udp 1473 (frag

3627414800+) (ttl 64 len 1500)

Intr-adevăr au fost generate două pachete IP

primul conţine doar un singur octet de date şi reprezintă ultimul fragment (bitul de more

fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest

lucru) care a fost spartă icircn bucăţi deplasamentul octetului primit in datagrama originală

este 1480

al doilea pachet este primul fragment din datagrama UDP şi conţine antetul UDP (din

cauza asta datele efective ocupă doar 1480 octeţi) deplasamentul este 0 şi bitul de more

fragments este setat (acest lucru este indicat de semnul ``+ de după deplasament)

După cum se poate observa ambele pachete poartă acelaşi număr de identificare (36274) Acest

lucru icircmpreună cu informaţiile date de flag-ul more fragments permite reconstrucţia la

destinaţie a datagramei UDP originale O problemă a acestui mod de fragmentare e că icircn cazul

pierderii unui fragment icircntreaga datagramă va fi compromisă şi va trebui retrimisă icircn icircntregime

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 7: udp tcp

Figura 72 Structura unui segment TCP

Antetul unui segment TCP cuprinde

port sursă - 16 biţi pentru specificarea portului aplicaţiei transmiţătoare

port destinaţie - 16 biţi pentru specificarea portului aplicaţiei ce recepţionează segmentul

TCP

Aceste două porturi icircmpreună cu adresele ale sursei şi destinaţiei conţinute icircn antet-ul IP

identifică icircn mod unic conexiunea Pentru o pereche formată dintr-o adresă IP şi un port

se foloseşte adesea denumirea de socket (denumire introdusă icircn specificaţiile iniţiale ale

protocolului TCP icircn RFC 793)

număr de secvenţă - 32 biţi

Pentru a asigura un serviciu de tip flux de octeţi TCP numerotează fiecare octet de date

utilizacircnd un număr de secvenţă Numărul de secvenţă din cadrul antetului TCP specifică

destinaţiei care este primul octet din fluxul trimis La iniţierea unei conexiuni se setează

flag-ul SYN şi se alege aleator un număr de secvenţă de icircnceput utilizacircnd un generator de

numere de secvenţă ISN (Initial sequence number) Numărul de secvenţă al primului

octet de date va fi numărul generat ISN plus 1 deoarece pachetul de iniţiere (cu SYN

setat) consumă şi el un număr de secvenţă Se va vedea mai departe că şi flag-ul de

terminare a conexiunii FIN consumă şi el un număr de secvenţă

confirmare - 32 biţi

Reprezintă numărul de secvenţă al octetului de date pe care transmiţătorul confirmării se

aşteaptă să-l primească Astfel dacă s-a recepţionat octetul cu numărul de secvenţă x (icircn

numerotaţia sursei) pachetul de confirmare va avea flag-ul ACK setat şi va conţine

numărul de confirmare x + 1 Trimiterea unui ACK nu consumă un număr de secvenţă

deoarece atacirct acest cacircmp cacirct şi flag-ul ACK fac parte din antet şi după stabilirea

conexiunii ambele cacircmpuri devin active Acest mecanism nu permite confirmări selective

pentru că numărul de secvenţă specifică pacircnă unde s-au recepţionat date De exemplu

dacă la destinaţie au ajuns octeţii 1-1024 şi următorul segment primit conţine octeţii

2049-3072 nu se poate trimite confirmare pentru cel de-al doilea segment deci

confirmarea va cuprinde numărul de secvenţă 1025

lungimea antetului - 4 biţi

Specifică dimensiunea antetului ca număr de cuvinte de 32 de biţi (4 octeţi) Antetul

poate avea icircntre 20 şi 60 de octeţi deci valoarea acestui cacircmp va fi icircntre 5 (5 x 4 = 20

octeţi) şi 15 (15 x 4 = 60)

6 biţi rezervaţi pentru utilizări viitoare

6 biţi de control reprezentacircnd următoarele flag-uri ce pot fi setate simultan

o URG - cacircmpul urgent pointer este valid

o ACK - cacircmpul de confirmare este valid

o PSH - destinaţia trebuie să trimită datele către nivelul aplicaţie cacirct mai devreme

o RST - se doreşte resetarea conexiunii

o SYN - iniţierea conexiunii

o FIN - icircnchiderea conexiunii

dimensiunea ferestrei - 16 biţi

Reprezintă numărul de octeţi (icircncepacircnd cu numărul de secvenţă conţinut icircn cacircmpul de

confirmare) pe care destinaţia e dispusă să-l primească Este limitat la 65535 octeţi dar

cu toate că pare o limită destul de mare există situaţii cacircnd se doresc valori mult mai

mari Icircn acest scop se folosesc nişte opţiuni speciale descrise ceva mai tacircrziu care permit

scalarea ferestrei

suma de control - 16 biţi

Această sumă de control acoperă icircntregul segment TCP (atacirct datele cacirct şi antetul TCP) şi

spre deosebire de UDP este obligatoriu să fie completat de transmiţător şi verificat de

receptor Dar ca şi icircn cazul UDP-ului la calculul sumei de control se ia in considerare şi

o zona specială de 12 octeţi ce cuprinde pentru re-verificare cacircmpuri din antetul IP

(adresa IP a sursei şi a destinaţiei)[aici tre sa vina o referire la poza cu pseudo-antetu]

După adăugarea acestui pseudo-antet datele se icircmpart icircn cuvinte de 16 biţi icircn vederea

calculării sumei de control adăugacircndu-se eventual şi un octet de aliniere

urgent pointer - 16 biţi

Este utilizat pentru specificarea deplasamentului ultimului octet de date trimis icircn regim

urgent Astfel ultimul octet din secvenţa urgentă se obţine adunacircnd acest cacircmp la

numărul de secvenţă Ce icircnseamnă acest mod urgent de transmitere există situaţii icircn care

aplicaţiile vor să trimită date `neordonate` Să presupunem că aplicaţia a trimis către

nivelul transport o cantitate mare de date dar la un moment dat observă ceva icircn neregulă

şi doreşte să anuleze operaţia Dacă trimite o comandă de anulare aceasta va fi adăugată

la sfacircrşitul şirului de octeţi deci nu se va putea icircmpiedica ajungerea acestora la nivelul

aplicaţie de la receptor Activacircnd modul urgent datele urgente (comanda de anulare) vor

fi plasate la icircnceputul pachetului Aplicaţiile mai cunoscute care folosesc acest mod sunt

Telnet Rlogin şi FTP

opţiuni - pacircnă la 40 de octeţi (figura 73)

Cele mai utilizate opţiuni sunt

o Sfacircrşit de opţiuni (end of option) - 1 octet

Este utilizat pentru alinierea datelor conţinute icircn cacircmpul de opţiuni Nu poate fi

utilizat decacirct o singură dată marcacircndu-se astfel sfacircrşitul opţiunilor şi icircnceperea

datelor efective Dacă pentru alinierea la un cuvacircnt de 32 de biţi e nevoie de mai

mult de 1 byte se va utiliza opţiunea no operation Orice apare după această

opţiune pacircnă la icircnceputul cuvacircntului următor de 32 de biţi e ignorat

o no operation - 1 octet

Utilizat pentru alinierea la cuvinte de 32 de biţi

o Dimensiunea maximă a segmentului (Maximum Segment Size (MSS)) - 16 biţi

Icircn ciuda denumirii defineşte lungimea maximă a datelor nu dimensiunea

icircntregului segment Poate lua valori icircntre 0 şi 65535 valoarea implicită fiind 536

Această opţiune e valabilă doar icircn pachetele de iniţiere a conexiunii (cele cu flag-

ul SYN setat) fiecare parte făcacircnd cunoscută dimensiunea maximă a datelor

dispusă să le primească icircntr-un pachet Icircn principiu cu cacirct această valoarea e mai

mare e mai bine (deoarece se recuperează din spaţiul ocupat de antetele TCP şi

IP) pacircnă cacircnd apare fragmentarea Valoarea maximă la care se poate seta este

MTU (Maximum Transfer Unit) minus dimensiunea antetului IP şi TCP (1460

octeţi icircn cazul Ethernet)

o Factor de scalare a ferestrei (Window scale factor) - 1 octet

Pentru situaţiile icircn care se doreşte utilizarea unei ferestre mai mare de 65535 bytes

se poate utiliza acest cacircmp pentru mărirea dimensiunii ferestrei Noua dimensiune

va fi Chiar dacă

factorul de scalare poate fi maxim 255 icircn cazul TCPIP el nu poate depăşi

valoarea 16 deoarece dimensiunea maximă a ferestrei nu poate fi mai mare decacirct

valoarea celui mai mare număr de secvenţă ( )

Acest factor se poate seta doar la iniţierea conexiunii Icircn timpul transferului de

date se poate modifica dimensiunea ferestrei dar factorul de scalare rămacircne

acelaşi Dacă cel care a iniţiat conexiunea a trimis icircn segmentul de iniţiere şi acest

factor dar icircn pachetul cu ACK destinatarul nu şi-a trimis şi el factorul atunci se la

considera 0 icircn ambele direcţii Invers dacă cel care solicită deschiderea

conexiunii nu setează factorul destinaţia nu va putea seta factorul de scalare

o Timestamp - 10 octeţi

Utilizat pentru reţinerea timpului icircn vederea calculării RTT (Round Trip Time)

Cacircmpul timestamp e completat de sursă icircn momentul trimiterii segmentului La

destinaţie valoarea este reţinută şi copiată icircn cacircmpul timestamp echo reply al

pachetului cu confirmarea RTT-ul este calculat de sursă făcacircnd diferenţa dintre

timpul curent şi această valoare

Figura Opţiuni TCP

3 Iniţierea şi terminarea unei conexiuni TCP

TCP este un protocol orientat conexiune deci presupune stabilirea unei căi virtuale icircntre sursă şi

destinaţie

Subsections

Protocolul de iniţiere

o 1 Deschiderea simultană

Protocolul de terminare

o 2 Terminarea simultană

o 3 Resetarea conexiunii

Diagrama de stări

Protocolul de iniţiere

Modul de transmisie icircn cazul protocolului TCP este full-duplex deci sunt transmise date

simultan icircn ambele direcţii Aceasta presupune că cel care iniţiază conexiunea trebuie să

primească aprobarea celuilalt capăt icircnainte de icircnceperea transferului de date sursa icircşi anunţă

intenţia de a iniţia o conexiune destinaţia trimite un pachet cu confirmarea cererii şi un pachet de

iniţiere a conexiunii de la el la sursă iar apoi sursa confirmă cererea primită de la destinaţie Paşii

2 şi 3 pot fi realizaţi prin trimiterea unui singur pachet de aceea protocolul de iniţiere este

cunoscut sub numele de three-way handshake

Icircn cadrul protocolului de iniţiere există 2 tipuri de cereri de iniţiere cerere activă (active open)

iniţiată de clientul ce doreşte să stabilească conexiunea cu serverul şi cerere pasivă (passive

open) din partea serverului

Cei 3 paşi sunt

1 Clientul trimite un segment cu flag-ul SYN setat şi care conţine portul sursă portul de la

destinaţie şi numărul de secvenţă generat iniţial (ISN) de la care se vor numerota octeţii

de la client către server Opţional se pot stabili parametrii conexiunii prin setarea lungimii

maxime a segmentelor (MSS) dispus să le primească de la server factorului de scalare a

ferestrei Acest prim segment nu conţine nici un parametru de confirmare şi de asemenea

nu are rost să conţine să seteze dimensiunea ferestrei

2 Al doilea segment e trimis de server şi are un rol dublu confirmă segmentul primit de la

client prin setarea flag-ului ACK şi completează numărul de secvenţă cu numărul de

secvenţă primit plus 1 şi al doilea rol iniţializează conexiunea de la el către client prin

setarea flag-ului SYN şi generarea unui număr de secvenţă iniţial ce va fi folosit icircn

numerotarea octeţilor de la server spre client Pe lacircngă aceasta trebuie să conţină

dimensiunea ferestrei şi opţional poate seta factorul de scalare şi dimensiunea maximă a

segmentului acceptat

3 Clientul trimite un segment cu confirmarea cererii din partea serverului (ACK setat +

completează numărul confirmat cu numărul de secvenţa primit + 1) Ca şi icircn cazul

pasului 2 trebuie să seteze dimensiunea ferestrei Acest pachet poate conţine date

Subsections

1 Deschiderea simultană

1 Deschiderea simultană

Se poate icircntacircmpla ca uneori cele două capete care vor să comunice să icircncerce să stabilească

conexiunea simultan Icircn acest caz după ce fiecare a trimis segmentul de iniţiere (iniţiere activă)

ambele vor trimite un segment cu SYN + ACK şi se va stabili o singură conexiune nu două

Protocolul de terminare

Oricare dintre cele două părţi poate solicita icircnchiderea conexiunii dar conexiunea fiind full-

duplex transferul de date icircn celălalt sens poate continua (această situaţie e denumită half-close)

O icircnchidere completă a unei conexiuni TCP presupune următorii paşi

1 Clientul trimite un segment cu flag-ul FIN activat solicitacircnd icircnchiderea conexiunii

2 Serverul trimite un segment ACK confirmacircnd primirea cererea Numărul de confirmare

se completează normal ca numărul de secvenţă primit + 1

3 Serverul continuă să trimită date către client şi cacircnd doreşte să icircnchidă şi el conexiunea

trimite un segment cu FIN activat

4 Clientul trimite un pachet ACK confirmacircnd icircnchiderea conexiunii

Cel care iniţiază primul procedura de icircnchidere (trimite primul FIN) realizează o icircnchidere activă

(active close) iar celălalt capăt o icircnchidere pasivă (passive close) Icircn mod normal cel care

realizează iniţierea activă va fi primul ce va trimite FIN dar oricare dintre cei doi poate icircnchide

activ conexiunea

Subsections

2 Terminarea simultană

3 Resetarea conexiunii

2 Terminarea simultană

Icircn mod similar cu deschiderea simultană există posibilitatea ca ambele capete ale conexiunii TCP

să iniţieze simultan procedura de icircnchidere a conexiunii Icircn acest caz ambele părţi vor trimite

FIN şi vor aştepta primirea unui ACK Icircn continuare fiecare va primi cererea de terminare şi va

trimite ACK Se observă că numărul de segmente transferate pentru realizarea icircnchiderii

conexiunii (4 segmente) este acelaşi ca la terminarea normală

3 Resetarea conexiunii

Există situaţii icircn care TCP doreşte resetarea conexiunii De exemplu dacă se solicită iniţierea

unei conexiuni la un port inexistent Icircn acest caz cealaltă parte va trimite un segment cu bitul

RST setat pentru a anula solicitarea O altă situaţie este atunci cacircnd se constată că celalalt capăt

al conexiunii nu răspunde un anumit timp (timeout)

Diagrama de stări

Toate evenimentele ce au loc icircn timpul stabilirii conexiunii transferului şi icircnchiderii conexiunii

pot fi rezumate printr-un automat finit cunoscut sub numele de diagrama de stări După cum

chiar numele sugerează este o maşină cu un număr limitat de stări O stare este păstrată pacircnă icircn

momentul apariţiei unui eveniment moment icircn care se poate trece icircn altă stare şisau efectua o

acţiune

Aceste stări posibile sunt (denumirile sunt asemănătoare cu cele utilizate de netstat) cele din

tabelul 71

Tabela Stările diagramei de stări TCP

Stare Descriere

CLOSED Nu există conexiune

LISTEN Serverul aşteaptă cereri de la clienţi

SYN_SENT Cerere de iniţiere (activă) a conexiunii Se

aşteaptă confirmarea

SYN_RCVD S-a primit o cerere de iniţiere conexiune

ESTABLISHED S-a stabilit conexiunea

FIN_WAIT_1 Aplicaţia a solicitat icircnchiderea conexiunii

FIN_WAIT_2 Serverul a acceptat icircnchiderea conexiunii

CLOSING Ambele părţi solicită simultan icircnchiderea

conexiunii

TIME_WAIT Conexiune icircnchisă dar se aşteaptă ca

pachetele retransmise să dispară

CLOSE_WAIT Serverul aşteaptă icircnchiderea dinspre partea

aplicaţiei

LAST_ACK Serverul a icircnchis conexiunea Aşteaptă

ultima confirmare

Icircn diagrama ilustrată icircn figura 74 putem observa 3 tipuri de tranziţii icircntre cele 11 stări tranziţii

ce corespund unei funcţionări normale pentru client (linii normale continue) pentru server (linii

normale icircntrerupte) şi tranziţii pentru situaţii nestandard (linii subţiri continue)

O comportarea normală pentru client presupune parcurgerea următoarelor stări CLOSED

SYN_SEND ESTABLISHED FIN_WAY_1 FIN_WAY_2 TIME_WAIT

Iniţial clientul TCP se află icircn starea CLOSED

Aşteptacircnd icircn starea CLOSED clientul poate primi de la aplicaţie o cerere de iniţiere

activă a unei conexiuni Trimite un segment SYN şi trece icircn starea SYN_SENT

Icircn starea SYN_SENT clientul aşteaptă de la server un segment ACK+SYN după care

trimite un ACK şi trece icircn starea ESTABLISHED Din acest moment poate icircncepe

transferul efectiv de date Clientul va rămacircne icircn această stare cacirct timp are de trimisprimit

date

Aflat icircn această stare clientul TCP poate primi din partea aplicaţiei o cerere de icircnchidere a

conexiunii Icircn acest caz va trimit un segment FIN şi trece icircn starea FIN_WAIT_1

Icircn această stare clientul aşteaptă ACK din partea serverului După ce-l primeşte

conexiunea icircntr-un sens se va icircnchide şi clientul trece icircn starea FIN_WAIT_2

Starea FIN_WAIT_2 durează pacircnă cacircnd primeşte cererea de icircnchidere a conexiunii FIN

din partea serverului Trimite ACK şi va trece icircn starea TIME_WAIT

Icircn această stare se va porni un timer cu valoarea setată la dublul timpului de viaţă estimat

pentru un segment de lungime maximă MSL (Maximum Segment Lifetime) Acest timer

permite retransmiterea ACK-ului icircn cazul icircn care acesta se pierde (celălalt capăt va da

timeout şi va retransmite segmentul FIN) Icircn tot acest time cei doi sockeţi (de la client şi

server) nu vor putea fi reutilizaţi Totodată pachetele icircntacircrziate care sosesc icircn această

perioadă sunt ignorate După expirarea acestui timer clientul revine icircn starea iniţială

CLOSED

Din punctul de vedere al unui server o comportare standard parcurge următoarele stări

CLOSED LISTEN SYN_RCVD ESTABLISHED CLOSE_WAIT şi LAST_ACK

Iniţial serverul TCP se află icircn starea CLOSED

Icircn această stare poate primi de la aplicaţia server o cerere de iniţiere activă şi trece icircn

starea LISTEN

Aflat icircn starea LISTEN serverului TCP poate recepţiona un segment SYN de la un client

TCP Icircn acest caz va trimite ACK+SYN şi va trece icircn starea SYN_RCVD

Icircn această stare serverul aşteaptă primirea confirmării de la client moment icircn care

conexiunea e stabilită icircn ambele sensuri şi se poate icircncepe transferul de date (starea

ESTABLISHED)

Clientul TCP poate solicita icircnchiderea conexiunii trimiţacircnd un segment FIN către server

Icircn acest caz serverul TCP trimite confirmarea şi trece icircn starea CLOSE_WAIT

Icircn această stare serverul aşteaptă să primească din partea programului server icircnchiderea

conexiunii moment icircn care va trimite către client un segment FIN şi trece icircn starea

LAST_ACK

Serverul aşteaptă primirea ultimei confirmări de la client după care revine icircn starea

CLOSED

Atacirct serverul cacirct şi clientul TCP se pot afla icircn oricare din cele 11 stări ale diagramei

Figura Diagrama de stări pentru TCP

4 Controlul fluxului

Dacă icircncă de la icircnceput s-a reuşit stabilirea formatului unui pachet TCP şi a modulului icircn care

trebuie să se facă icircnchiderea şi deschiderea unei conexiuni nu acelaşi lucru se poate spune şi

despre modul icircn care ar trebui să se realizeze controlul fluxului Ţinacircnd seama icircnsă că din 1989

(de cacircnd datează RFC-ul 2581 cel despre care am menţionat că specifică icircn mod clar modul icircn

care trebuie să se comporte o implementare de TCP) TCP-ul a rămas neschimbat putem să icircl

considerăm un rezultat important al domeniului reţelor de calculatoare

Icircn cele ce urmează vom icircnţelege prin controlul fluxului totalitatea algoritmilor care permit

atingerea unei viteze de transfer punct-la-punct cacirct mai mare pentru toate conexiunile existente

Icircn principal aceşti algoritmi stabilesc modul icircn care segmentele şi confirmările trebuie trimise şi

ce acţiuni trebuie executate icircn situaţiile icircn care răspunsurile aşteptate de la celălalt capăt icircntacircrzie

să vină

Subsections

Icircntacircrzierea confirmărilor

Algoritmul Nagle

Fereastra glisantă

Slow start

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Evitarea congestiei

Fast Retransmission Fast Recovery

Sindromul ``Silly Window

TCP Keepalive Timer

Icircntacircrzierea confirmărilor

O modalitate simplă de generare a confirmărilor este de a trimite cacircte una pentru fiecare segment

primit Această politică prezintă avantajul de a face comunicaţia self-clocking icircnsă este

ineficientă dacă segmentele care nu conţin decacirct confirmări sunt urmate la scurtă distanţă (cacircteva

zeci de milisecunde) de segmente ce conţin date efective Pentru a evita această situaţie se

procedează2 la icircntacircrzierea (200ms este o valoare uzuală icircn RFC 1122 se specifică o valoare

maximă de 500ms) a segmentelor care conţin doar confirmări Această strategie face posibil ca

un răspuns generat de primirea unor date să plece sper celălalt capăt icircn acelaşi segment cu

confirmarea

Observaţie deoarece este dificil de menţinut timere pentru fiecare confirmare diferenţa de

200ms este calculată de un timer global Din acest motiv modul efectiv de comportare poate fi

descris şi icircn felul următor cacircnd un segment nu conţine decacirct o confirmare el este pus icircntr-o

coadă ce va fi inspectată de un proces care din 200 icircn 200 ms trimite tot ce s-a acumulat icircn

coada

Footnotes

2

Acest comportament a fost propus de David D Clark icircn iulie 1982 icircn RFC 813

Algoritmul Nagle

Acest algoritm3 icircncearcă să icircmbunătăţească performanţele exploatacircnd următoarea caracteristică

foarte des icircntacirclnită icircn dialogul dintre două staţii dacă se icircncearcă trimiterea unor date de

dimensiune mică icircnsă există icircncă date neconfirmate de partener atunci ele sunt buffer-ate şi

trimise icircntr-un segment mai mare cacircnd soseşte confirmarea aşteptată Icircn acest fel se poate evita

generarea datagramelor mici (tinygrame) icircn situaţia unei legături lente Icircn cazul unei legături

rapide confirmările vor veni repede şi icircntacircrzierea introdusă de algoritm va neglijabilă

Există icircnsă şi cazuri icircn care acest algoritm duce la deprecierea performanţelor mesajele scurte

generate de mişcările mouse-ului icircn cazul folosirii unui server X Window sau utilizarea tastelor

care trimit mai mult de un caracter (secvenţe escape) Pentru a rezolva aceste inconveninte API-

ul de utilizare a TCP-ului trebuie să ofere o modalitate de a dezactiva acest algoritm (icircn sistemele

bazate pe sockeţi există icircn acest scop opţiunea TCP_NODELAY)

Footnotes

algoritm3

Algoritmul aparţinacircnd lui John Nagle a fost propus icircn ianuarie 1984 icircn RFC 896

Fereastra glisantă

Algoritmul implementat de TCP pentru a implementa transferul sigur de date este cunoscut icircn

teorie sub numele de Go-Back-N Icircn acest algoritm se utilizează numere de secvenţă pentru a

distinge pachetele icircntre ele şi o coadă (dimensiunea maximă a cozii reprezintă fereastra) de

pachetele a căror confirmare se aşteaptă Pachetele se icircmpart icircn 4 categorii

1 pachete trimis şi pentru care s-a primit confirmare

2 pachete trimise şi pentru care se aşteaptă icircncă confirmarea

3 pachete care nu au fost trimise icircncă dar care nu depăşesc limitele ferestrei şi deci pot fi

trimise

4 pachete care icircncă nu au fost trimite şi care nici nu vor putea fi trimise decacirct după ce au

fost trimise toate pachetele din categoria 3 şi s-au primit o parte din confirmările la

pachetele din categoria 2

Dacă confirmările pentru pachetele din categoria 2 icircntacircrzie prea mult (un mecanism de timer-e

informează asupra acestui lucru) atunci ele vor fi retrimise Icircn versiunea iniţială TCP-ul nu

permitea decacirct confirmări pozitive ceea ce icircnseamnă că avansarea ferestrei se va icircmpotmoli la

segmentele neconfirmate Cum se poate evita aceasta situaţie vom discuta icircn detaliu icircn capitolele

următoare O soluţie foarte radicală o constituie introducerea de confirmări selective (acest lucru

este realizat de RFC 2018 din octombrie 1996) Această modifică face ca TCP-ul actual să fie un

hibrid de Go-Back-N şi Selective Repeat

Deoarece dimensiunea ferestrei este anunţată la fiecare segment un client lent poate ca pe măsură

ce trimite confirmările să informeze despre progresul icircnregistrat la livrarea datelor următorului

nivel (aplicaţie) Dacă datele vin prea repede pentru viteza cu care clientul procesează datele

fereastra fereastra se va dimiua şi chiar icircnchide (acest lucru se realizează anunţacircnd o fereastră de

dimensiune zero) Cum se realizează efectiv redeschiderea vom analiza icircntr-un capitol viitor

Slow start

Un transfer de date TCP poate să icircnceapă prin transmiterea de segmente pacircnă la umplerea

icircntregii ferestre după care fie se primesc confirmări care vor permite unor noi pachete să fie

trimise fie vor expira timer-ele de retransmisie şi se va icircncepe retrimiterea pachetelor de la

icircnceputul ferestrei Din păcate un astfel de comportament poate duce la pomparea icircn reţea a unui

număr de pachete prea mare pentru capacitatea disponibilă efectiv icircnrăutăţind congestia Pentru

a evita acest lucru s-a propus următoarea soluţie4 iniţial se trimite un segment după primirea

confirmării lui se trimit două segmente după sosirea confirmărilor pentru ele se trimit patru

segmente şi aşa mai departe La un moment dat fie vor icircncepe să se piardă segmente (un indiciu

că s-a atins capacitatea maximă a canalului) fie se va umple fereastra pe care o anunţă cel care

primeşte Trebuie să remarcam că datorită creşterii exponenţiale a numărului de segmente se va

atinge destul de repede una din cele două situaţii

Modalitatea efectivă de implementare a acestui algoritm are la bază utilizarea unei ferestre de

congestie (congestion window cwnd) care este iniţializată cu dimensiunea unui segment (cwnd

se calculează icircn octeţi) şi la fiecare pas este dublată fereastra efectivă din cadrul căreia se pot

trimite segmente este dată de minimul dintre ultima fereastra comunicată de partener şi cwnd

Footnotes

soluţie4

Soluţia aparţine lui V Jacobson şi a fost prezentată icircn 1988 la conferinţă ACM

SIGCOMM-88

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Deoarece TCP trebuie să funcţioneze icircn condiţii variate de latenţă modul icircn care se face

retransmiterea trebuie să fie cacirct mai flexibil (şi simplu icircn acelaşi timp pentru a introduce un

overhead cacirct mai mic) Timpul cacirct se aşteaptă venirea unei confirmări (retransmission timeout

RTO) este calculat prin cronometrarea timpului care icirci ia unui segment trimis să fie confirmat

Pentru o anumită conexiune se cronometrează cacircte un singur segment la un moment dat iar pe

baza RTT-ului măsurat se actualizează valoare RTO-ului

Icircn RFC 793 formula de calcul a RTO-ului este următoarea

unde este ultimul RTT măsurat este o estimare ponderată pentru RTT este un coeficient

de ponderare care icircn general are valoarea iar este un coeficient cu o valoare recomandată

de După cum se poate observa icircn valoarea lui este inclusă icircn mare măsură vechea valoarea

Icircn acest fel ajustarea RTT-ului se face treptat Din păcate acest mod de calcul nu funcţionează

bine la variaţii mari ale RTT-ului ducacircnd la creşterea numărului de retransmisii exact atunci

cacircnd fenomenul de congestie icircncepe să apară

Pentru a remedia aceste neajunsuri V Jacobsen a propus icircn 1988 o nouă metodă de calcul o

metodă care ţine seama seamă şi de modul icircn care variază diferenţa dintre RTT-uri Formulele

folosite sunt următoarele

unde este un estimare pentru media RTT-urilor este o estimare pentru abaterea RTT-urilor

faţă de medie (o aproximaţie suficientă pentru abaterea pătratică medie care icircnsă este mult mai

costisitor de calculat) este diferenţa dintre RTT-ul măsurat ( ) şi estimarea curentă ( )

Coeficientul cu care este actualizată estimarea curentă are valoarea de iar cel cu care este

actualizat estimarea abaterii este La stabilirea unei conexiuni valorile pentru şi sunt

alese astfel icircncacirct să rezulte un RTT de secunde şi un de 3 secunde (aceste recomandări

sunt făcute de RFC 1122)

Dacă pentru un anumit segment nu se primeşte confirmarea icircn intervalul indicat de el va fi

retrimis şi noul este dublat Valoarea maximă admisă pentru este de 240 secunde

Deoarece icircn cazul retrimiterilor nu se poate determina cu exactitate căruia din segmentele trimise

aparţine confirmarea actualizarea estimărilor este amacircnată pacircnă cacircnd se reuşeşte trimiterea

corectă (s-a primit confirmare) fără retransmitere(``din prima) a unui segment Acest artificiu

(deloc neimportant) care permite evitarea actualizarea eronată a estimărilor este cunoscut sub

numele de algoritmul lui Karn şi a fost propus icircn 1987 de P Karn şi C Partridge

Evitarea congestiei

Dacă cei doi parteneri care comunică prelucrează datele suficient de repede şi vor să transfere un

volum mare de date atunci limitarea de care se vor lovi este cea dată de viteza reţelei Din cauza

modului ``best-effort pe care IP-ul icircl oferă cacircnd canalul de comunicaţie este saturat o parte din

segmentele TCP se vor pierde Icircn mod poate paradoxal atacirct transmiţătorului cacirct şi receptorul se

pot afla icircn poziţia de a fi primii icircn detectarea pierderii unui segment Unul din indiciile de la

transmiţător care semnalează pierderea unui segment este (icircn mod evident) apariţia 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 icircn varianta iniţială nu

permite decacirct confirmări pozitive singurul lucru pe care receptorul icircl poate face este ca la fiecare

segment out-of-order primit să trimită o confirmare indicacircnd prin aceasta că la el continuă să

vină segmente icircnsă cel indicat de numărul de secvenţă de confirmare lipseşte Primirea acestor

confirmări multiple este al doilea mod icircn care transmiţătorul poate afla de apariţia congestiei

Algoritmul ce trebuie aplicat icircn momentul icircn care se detectează apariţia congestiei este cunoscut

sub numele de ``evitarea congestiei (congestion avoidence) Principiul care stă la baza lui este

ca la apariţia congestiei fie să se treacă la o incrementare liniară a dimensiunii ferestrei dacă

congestia a fost detectată ca urmare a primirii unor confirmări identice repetate fie să se reia

slow start-ul icircn cazul icircn care congestia s-a detectat prin expirarea unui timer de timeout

Implementarea acestui algoritm se bazează pe utilizarea unui nou contor (sstresh) care să indice

dimensiunea ferestrei de la care se trece de la incrementarea exponenţială la cea liniară

Algoritmul efectiv este următorul

1 la stabilirea unei noi conexiuni se pleacă cu sstresh iniţializat la valoare de 64K şi cwnd

la dimensiunea unui segment

2 trimiterea de segmente se face fără a depăşi minimul dintre fereastra publicată de partener

(pentru a nu depăşi capacitatea de procesesare a partenerului) şi cwnd-ul curent (pentru a

nu depăşi limita impusă de capacitatea reţelei)

3 la apariţia congestiei sstresh este setat la jumătatea valorii ferestrei curente (minimul

dintre fereastra anunţată de partener şi cwnd icircnsă cel puţin dimensiunea corespunzătoare

pentru două segmente) dacă congestia a fost detectată prin expirarea unui timer de

timeout atunci cwnd este iniţializat cu dimensiunea unui segment

4 la primirea unei confirmări incrementarea se face icircn două moduri icircn funcţie de relaţie icircn

care se află cwnd şi sstresh

1 dacă cwnd e mai mic sau egal cu sstresh se face incrementarea exponenţială

caracteristică slow start-ului (care de fapt nu e deloc slow icircn cazul de faţă)

2 dacă cwnd e mai mare ca sstresh atunci se face o incrementare cu dimensiunea

unui segment

Fast Retransmission Fast Recovery

După cum am văzut un receptor care primeşte segmente out-of-order va trimite transmiţătorului

confirmări duplicate Algoritmul denumit ``fast retransmission recomandă următoarele două

comportamenet

1 un receptor care detectează segmente out-of order trebuie să nu icircntacircrzie trimiterea de

confirmări (după cum am văzut icircn general confimările sunt icircntacircrziate micşora numărul de

pachete fără date care sunt transferate)

2 un transmiţător care care primeşte mai mult de trei confirmări duplicate trebuie să

retrimită segmentul indicat ca fiind neprimit de confirmările icircn cauză fără a aştepta

expirarea timer-ul de timeout

Algoritmul de ``fast recovery icircncearcă să optimizeze şi mai mult comportamentul

transmiţătorului care detectează un număr de trei sau mai multe confimări duplicate Mai exact el

recomandă trecerea la actualizarea liniară a ferestrei (congestion avoidance) Acest tip de

comportament se poate justifica prin următorul raţionament deoarece icircncă mai sunt transferate

date icircntre cei doi parteneri (şi acest lucru se icircntacircmplă sigur de vreme ce sosesc confirmări

duplicate icircn cazul acesta) icircnseamnă că transferul nu este afectat de o congestie severă şi prin

urmare trecerea la slow start nu e (icircncă) necesară (slow start-ul eliberează aproape complet

canalul deoarece cwnd este resetat la dimensiunea unui singur segment)

Cei doi algoritmi pot fi implementaţi icircn felul următor

1 cacircnd se detectează trei confirmări consecutive identice se setează sstresh la jumătate din

valoarea cwnd se retransmite segmentul care s-a pierdut şi se setează cwnd la valoarea

egală cu sstresh plus dimensiunea a trei segmente (acest lucru va face ca algoritmul de

incrementare a cwnd să treacă la incrementare liniară)

2 la fiecare confirmare duplicată care mai soseşte se incrementează cwnd se incrementează

cu dimensiunea unui segment

3 cacircnd icircncetează primirea de confirmări duplicate (segmentul retrimis a ajuns cu bine la

receptor şi s-a trimis o confirmare care acoperă segmentul care se pierduse iniţial) cwnd

este setat la valoarea sstresh

Sindromul ``Silly Window

Protocoalele bazate pe fereastră glisantă (cum este şi TCP-ul) pot să ajungă icircn situaţia deloc

fericită de trimite un număr mare de segmente mici icircn loc de segmente de dimensiune maximă

Acest tip de comportament este cunoscut sub numele de sindromul ``silly window

O modalitate prin care TCP-ul poate să cadă victimă acestui tip de comportament este

deschiderea de ferestre cu dimensiune foarte mică O altă situaţia nefericită este cea icircn care un

transmiţător este ``lacom şi trimite date indiferent de cacirct de mică este fereastra (după cum vom

vedea imediat uneori are sens şi un astfel de comportament) Algoritmul de evitare a acestor

neajunsuri este următorul

1 un receptor nu trebuie să anunţe deschideri de ferestre mici Mai exact nu se recomandă

anunţarea unei incrementări a ferestrei mai mică decacirct dimensiunea unui segment (MSS)

sau jumătate din buffer-ul aflat la dispoziţia receptorului oricare din ele e mai mică

2 un transmiţător va trimite date doar icircn următoarele cazuri

1 se poate trimite un segment icircntreg

2 se poate trimite jumătate din dimensiunea celei mai mari ferestre pe care

partenerul a publicat-o pacircnă acum

3 toate datele trimise pacircnă acum au fost confirmate sau algoritmul Nagle este

dezactivat şi se trimit toate datele care sunt icircn buffer-ul de trimitere

Cacircteva justificări cazul 2b tratează cazul icircn care partenerul anunţă ferestre mai mici decacirct

dimensiunea unui segment iar cazul 2c impune condiţiile respectării algoritmului Nagle după

cum se vede dacă algoritmul Nagle este activ şi s-au acumulat destul date mai exact cacirct

dimensiunea unui segment el va fi trimis chiar dacă există segmente neconfirmate Pentru

implementarea comportamentului impus de 2b un transmiţător trebuie să ţină evidenţa celei mai

mari ferestre pe care partenerul a anunţat-o Ţinacircnd seama că dimensiunea acestor buffer-e nu se

modifică acest mod de a icircncerca determinarea lor este suficient

O altă problemă legată tot de ferestre este cazul icircnchiderii acesteia Un mod icircn care s-ar putea

anunţa redeschiderea este trimiterea de către receptor a unei confirmări (duplicat) care să anunţe

redeschiderea la o anumită valoare a ferestrei Deoarece acest pachet nu trebuie confirmat icircn mod

special şi s-ar putea să se piardă se poate ajunge icircn situaţia icircn care receptorul a anunţat

redeschiderea ferestrei segmentul s-a pierdut iar transmiţătorul icircncă mai icircl mai aşteaptă pentru a

putea continua transferul Rezolvarea la această problemă s-a făcut prin impunerea unui alt

comportament

1 transmiţătorul va trimite segmente cu dimensiunea datelor de un octet prin care sondează

deschiderea ferestrei intervalul la care se sondează redeschiderea ferestrei se dublează

(exponenţial backoff) icircn RFC 793 dimensiunea maximă recomandată este de 2 minute

icircnsă icircn RFC 1122 se specifică că maximul este acelaşi cu cel din cazul retransmisiei (240

secunde)

2 receptorul trebuie să refuze aceste pachete răspunzacircnd cu segmente de confirmare care

indică neprimirea octetului respectiv

Observaţie timer-ul special necesar pentru implementare la transmiţător a comportamentului de mai sus este cunoscut sub numele de ``TCP Persistent Timer Numele este justificat de faptul că sondarea deschiderii se va face pacircnă cacircnd fie fereastra se deschide fie conexiunea se icircntrerupe TCP Keepalive Timer

Un lucru interesant despre TCP este faptul că dacă nivelele superioare nu comunică nimic icircntre

ele pentru o perioadă lungă 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 icircn care au trecut cu succes de faza stabilirii legăturii Dacă nivelurile

inferioare (reţeaIP fizic) devin temporar indisponibile cacirct tip cei doi nu vor să comunice atunci

acest lucru nu va perturba icircn nici un fel activitatea şi acest lucru este acceptabil Problemele

icircncep să apară icircn momentul icircn care cei doi doresc să comunice şi nivelele inferioare nu mai

permit acest lucru Evident că cel care va dori să comunice ceva va detecta icircntreruperea legăturii

şi va icircnchide conexiunea Ce se icircntacircmplă icircnsă dacă celălalt capăt nu are nimic de comunicat (de

exemplu este un server care oferă anumite servicii) Pentru el legătura va fi icircn continuare activă

şi icircn general anumite resurse vor fi rezervate pentru aceasta Rezolvarea acestei situaţii este dată

de introducerea unei mecanism de sondare a stării legăturii pe baza unui timer (TCP Keepalive

Timer) care se declanşează din două icircn două ore La fiecare expirare a timer-ului se trimite un

segment fără date care confirmă datele primite pacircnă atunci Răspunsul care trebuie primit este tot

un segment fără date care confirmă datele primite de partener (practic o re-publicare a stării celor

doi parteneri) Dacă răspunsul nu este primit timp de 75 secunde atunci segmentul va fi retrimis

Dacă după 10 astfel de icircncercări tot nu s-a primit nici un răspuns atunci conexiunea se va

considera terminată şi se va anunţa nivelul superior asupra acestui lucru

Observaţii

dacă o staţie primeşte segmente de keepalive despre conexiuni care nu mai sunt active

(de exemplu a fost resetat) atunci va răspunde cu segmente de reset (acesta e un procedeu

standard)

RFC 1122 specifică că facilitatea de keepalive trebuie activată icircn mod explicit

3 Studii de caz

Subsections

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

1 Fragmentarea pachetelor UDP

Deoarece UDP-ul este un serviciu fără conexiune toate datele pe care le primeşte de la nivelul

superior sunt icircncapsulate icircntr-o singură datagramă UDP care apoi va forma un pachet IP Dacă

pachetul IP astfel obţinut este prea mare atunci mecanismele IP de fragmentare icircl vor sparge icircn

bucăţi Exemplul următor icircncearcă să studieze exact acest fenomen

Pe maşina athos rulează un server de UDP pe portul 50007 Pe o altă maşină frodo aflată icircn

reţeaua locală este rulat un client care poate fi configurat să trimită un pachet UDP de o anumită

lungime Pentru a putea observa ce se icircntacircmplă pe athos este rulat tcpdump

Deoarece MTU-ul pentru o reţea Ethernet este icircn general 1500 şi antetul IP plus cel UDP ocupă

20 + 8 = 28 octeţi o datagramă UDP de dimensiune 1472 ar trebui sa fie trimisă nefragmentată

Pentru siguranţă folosind clientul de pe athos s-a trimis mai icircntacirci o datagramă UDP cu 1471

octeţi de date şi apoi icircncă una cu 1472 Pentru ambele tcpdump a indicat trimiterea lor fără

fragmentare

182556721144 frodonoi33274 gt athosnoi50007 udp 1471 (DF) (ttl 64 id

51481 len 1499)

182559846764 frodonoi33274 gt athosnoi50007 udp 1472 (DF) (ttl 64 id

51793 len 1500)

La o dimensiune de 1473 ar trebui ca trimiterea să genereze două pachete IP unul care să

conţină primii antetul UDP plus primii 1472 octeţi de date şi icircncă un pachet IP care conţine un

singur octet Iată ce indică tcpdump-ul

182605705813 frodonoi gt athosnoi udp (frag 3627411480) (ttl 64 len

21)

182605706116 frodonoi33274 gt athosnoi50007 udp 1473 (frag

3627414800+) (ttl 64 len 1500)

Intr-adevăr au fost generate două pachete IP

primul conţine doar un singur octet de date şi reprezintă ultimul fragment (bitul de more

fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest

lucru) care a fost spartă icircn bucăţi deplasamentul octetului primit in datagrama originală

este 1480

al doilea pachet este primul fragment din datagrama UDP şi conţine antetul UDP (din

cauza asta datele efective ocupă doar 1480 octeţi) deplasamentul este 0 şi bitul de more

fragments este setat (acest lucru este indicat de semnul ``+ de după deplasament)

După cum se poate observa ambele pachete poartă acelaşi număr de identificare (36274) Acest

lucru icircmpreună cu informaţiile date de flag-ul more fragments permite reconstrucţia la

destinaţie a datagramei UDP originale O problemă a acestui mod de fragmentare e că icircn cazul

pierderii unui fragment icircntreaga datagramă va fi compromisă şi va trebui retrimisă icircn icircntregime

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 8: udp tcp

dacă la destinaţie au ajuns octeţii 1-1024 şi următorul segment primit conţine octeţii

2049-3072 nu se poate trimite confirmare pentru cel de-al doilea segment deci

confirmarea va cuprinde numărul de secvenţă 1025

lungimea antetului - 4 biţi

Specifică dimensiunea antetului ca număr de cuvinte de 32 de biţi (4 octeţi) Antetul

poate avea icircntre 20 şi 60 de octeţi deci valoarea acestui cacircmp va fi icircntre 5 (5 x 4 = 20

octeţi) şi 15 (15 x 4 = 60)

6 biţi rezervaţi pentru utilizări viitoare

6 biţi de control reprezentacircnd următoarele flag-uri ce pot fi setate simultan

o URG - cacircmpul urgent pointer este valid

o ACK - cacircmpul de confirmare este valid

o PSH - destinaţia trebuie să trimită datele către nivelul aplicaţie cacirct mai devreme

o RST - se doreşte resetarea conexiunii

o SYN - iniţierea conexiunii

o FIN - icircnchiderea conexiunii

dimensiunea ferestrei - 16 biţi

Reprezintă numărul de octeţi (icircncepacircnd cu numărul de secvenţă conţinut icircn cacircmpul de

confirmare) pe care destinaţia e dispusă să-l primească Este limitat la 65535 octeţi dar

cu toate că pare o limită destul de mare există situaţii cacircnd se doresc valori mult mai

mari Icircn acest scop se folosesc nişte opţiuni speciale descrise ceva mai tacircrziu care permit

scalarea ferestrei

suma de control - 16 biţi

Această sumă de control acoperă icircntregul segment TCP (atacirct datele cacirct şi antetul TCP) şi

spre deosebire de UDP este obligatoriu să fie completat de transmiţător şi verificat de

receptor Dar ca şi icircn cazul UDP-ului la calculul sumei de control se ia in considerare şi

o zona specială de 12 octeţi ce cuprinde pentru re-verificare cacircmpuri din antetul IP

(adresa IP a sursei şi a destinaţiei)[aici tre sa vina o referire la poza cu pseudo-antetu]

După adăugarea acestui pseudo-antet datele se icircmpart icircn cuvinte de 16 biţi icircn vederea

calculării sumei de control adăugacircndu-se eventual şi un octet de aliniere

urgent pointer - 16 biţi

Este utilizat pentru specificarea deplasamentului ultimului octet de date trimis icircn regim

urgent Astfel ultimul octet din secvenţa urgentă se obţine adunacircnd acest cacircmp la

numărul de secvenţă Ce icircnseamnă acest mod urgent de transmitere există situaţii icircn care

aplicaţiile vor să trimită date `neordonate` Să presupunem că aplicaţia a trimis către

nivelul transport o cantitate mare de date dar la un moment dat observă ceva icircn neregulă

şi doreşte să anuleze operaţia Dacă trimite o comandă de anulare aceasta va fi adăugată

la sfacircrşitul şirului de octeţi deci nu se va putea icircmpiedica ajungerea acestora la nivelul

aplicaţie de la receptor Activacircnd modul urgent datele urgente (comanda de anulare) vor

fi plasate la icircnceputul pachetului Aplicaţiile mai cunoscute care folosesc acest mod sunt

Telnet Rlogin şi FTP

opţiuni - pacircnă la 40 de octeţi (figura 73)

Cele mai utilizate opţiuni sunt

o Sfacircrşit de opţiuni (end of option) - 1 octet

Este utilizat pentru alinierea datelor conţinute icircn cacircmpul de opţiuni Nu poate fi

utilizat decacirct o singură dată marcacircndu-se astfel sfacircrşitul opţiunilor şi icircnceperea

datelor efective Dacă pentru alinierea la un cuvacircnt de 32 de biţi e nevoie de mai

mult de 1 byte se va utiliza opţiunea no operation Orice apare după această

opţiune pacircnă la icircnceputul cuvacircntului următor de 32 de biţi e ignorat

o no operation - 1 octet

Utilizat pentru alinierea la cuvinte de 32 de biţi

o Dimensiunea maximă a segmentului (Maximum Segment Size (MSS)) - 16 biţi

Icircn ciuda denumirii defineşte lungimea maximă a datelor nu dimensiunea

icircntregului segment Poate lua valori icircntre 0 şi 65535 valoarea implicită fiind 536

Această opţiune e valabilă doar icircn pachetele de iniţiere a conexiunii (cele cu flag-

ul SYN setat) fiecare parte făcacircnd cunoscută dimensiunea maximă a datelor

dispusă să le primească icircntr-un pachet Icircn principiu cu cacirct această valoarea e mai

mare e mai bine (deoarece se recuperează din spaţiul ocupat de antetele TCP şi

IP) pacircnă cacircnd apare fragmentarea Valoarea maximă la care se poate seta este

MTU (Maximum Transfer Unit) minus dimensiunea antetului IP şi TCP (1460

octeţi icircn cazul Ethernet)

o Factor de scalare a ferestrei (Window scale factor) - 1 octet

Pentru situaţiile icircn care se doreşte utilizarea unei ferestre mai mare de 65535 bytes

se poate utiliza acest cacircmp pentru mărirea dimensiunii ferestrei Noua dimensiune

va fi Chiar dacă

factorul de scalare poate fi maxim 255 icircn cazul TCPIP el nu poate depăşi

valoarea 16 deoarece dimensiunea maximă a ferestrei nu poate fi mai mare decacirct

valoarea celui mai mare număr de secvenţă ( )

Acest factor se poate seta doar la iniţierea conexiunii Icircn timpul transferului de

date se poate modifica dimensiunea ferestrei dar factorul de scalare rămacircne

acelaşi Dacă cel care a iniţiat conexiunea a trimis icircn segmentul de iniţiere şi acest

factor dar icircn pachetul cu ACK destinatarul nu şi-a trimis şi el factorul atunci se la

considera 0 icircn ambele direcţii Invers dacă cel care solicită deschiderea

conexiunii nu setează factorul destinaţia nu va putea seta factorul de scalare

o Timestamp - 10 octeţi

Utilizat pentru reţinerea timpului icircn vederea calculării RTT (Round Trip Time)

Cacircmpul timestamp e completat de sursă icircn momentul trimiterii segmentului La

destinaţie valoarea este reţinută şi copiată icircn cacircmpul timestamp echo reply al

pachetului cu confirmarea RTT-ul este calculat de sursă făcacircnd diferenţa dintre

timpul curent şi această valoare

Figura Opţiuni TCP

3 Iniţierea şi terminarea unei conexiuni TCP

TCP este un protocol orientat conexiune deci presupune stabilirea unei căi virtuale icircntre sursă şi

destinaţie

Subsections

Protocolul de iniţiere

o 1 Deschiderea simultană

Protocolul de terminare

o 2 Terminarea simultană

o 3 Resetarea conexiunii

Diagrama de stări

Protocolul de iniţiere

Modul de transmisie icircn cazul protocolului TCP este full-duplex deci sunt transmise date

simultan icircn ambele direcţii Aceasta presupune că cel care iniţiază conexiunea trebuie să

primească aprobarea celuilalt capăt icircnainte de icircnceperea transferului de date sursa icircşi anunţă

intenţia de a iniţia o conexiune destinaţia trimite un pachet cu confirmarea cererii şi un pachet de

iniţiere a conexiunii de la el la sursă iar apoi sursa confirmă cererea primită de la destinaţie Paşii

2 şi 3 pot fi realizaţi prin trimiterea unui singur pachet de aceea protocolul de iniţiere este

cunoscut sub numele de three-way handshake

Icircn cadrul protocolului de iniţiere există 2 tipuri de cereri de iniţiere cerere activă (active open)

iniţiată de clientul ce doreşte să stabilească conexiunea cu serverul şi cerere pasivă (passive

open) din partea serverului

Cei 3 paşi sunt

1 Clientul trimite un segment cu flag-ul SYN setat şi care conţine portul sursă portul de la

destinaţie şi numărul de secvenţă generat iniţial (ISN) de la care se vor numerota octeţii

de la client către server Opţional se pot stabili parametrii conexiunii prin setarea lungimii

maxime a segmentelor (MSS) dispus să le primească de la server factorului de scalare a

ferestrei Acest prim segment nu conţine nici un parametru de confirmare şi de asemenea

nu are rost să conţine să seteze dimensiunea ferestrei

2 Al doilea segment e trimis de server şi are un rol dublu confirmă segmentul primit de la

client prin setarea flag-ului ACK şi completează numărul de secvenţă cu numărul de

secvenţă primit plus 1 şi al doilea rol iniţializează conexiunea de la el către client prin

setarea flag-ului SYN şi generarea unui număr de secvenţă iniţial ce va fi folosit icircn

numerotarea octeţilor de la server spre client Pe lacircngă aceasta trebuie să conţină

dimensiunea ferestrei şi opţional poate seta factorul de scalare şi dimensiunea maximă a

segmentului acceptat

3 Clientul trimite un segment cu confirmarea cererii din partea serverului (ACK setat +

completează numărul confirmat cu numărul de secvenţa primit + 1) Ca şi icircn cazul

pasului 2 trebuie să seteze dimensiunea ferestrei Acest pachet poate conţine date

Subsections

1 Deschiderea simultană

1 Deschiderea simultană

Se poate icircntacircmpla ca uneori cele două capete care vor să comunice să icircncerce să stabilească

conexiunea simultan Icircn acest caz după ce fiecare a trimis segmentul de iniţiere (iniţiere activă)

ambele vor trimite un segment cu SYN + ACK şi se va stabili o singură conexiune nu două

Protocolul de terminare

Oricare dintre cele două părţi poate solicita icircnchiderea conexiunii dar conexiunea fiind full-

duplex transferul de date icircn celălalt sens poate continua (această situaţie e denumită half-close)

O icircnchidere completă a unei conexiuni TCP presupune următorii paşi

1 Clientul trimite un segment cu flag-ul FIN activat solicitacircnd icircnchiderea conexiunii

2 Serverul trimite un segment ACK confirmacircnd primirea cererea Numărul de confirmare

se completează normal ca numărul de secvenţă primit + 1

3 Serverul continuă să trimită date către client şi cacircnd doreşte să icircnchidă şi el conexiunea

trimite un segment cu FIN activat

4 Clientul trimite un pachet ACK confirmacircnd icircnchiderea conexiunii

Cel care iniţiază primul procedura de icircnchidere (trimite primul FIN) realizează o icircnchidere activă

(active close) iar celălalt capăt o icircnchidere pasivă (passive close) Icircn mod normal cel care

realizează iniţierea activă va fi primul ce va trimite FIN dar oricare dintre cei doi poate icircnchide

activ conexiunea

Subsections

2 Terminarea simultană

3 Resetarea conexiunii

2 Terminarea simultană

Icircn mod similar cu deschiderea simultană există posibilitatea ca ambele capete ale conexiunii TCP

să iniţieze simultan procedura de icircnchidere a conexiunii Icircn acest caz ambele părţi vor trimite

FIN şi vor aştepta primirea unui ACK Icircn continuare fiecare va primi cererea de terminare şi va

trimite ACK Se observă că numărul de segmente transferate pentru realizarea icircnchiderii

conexiunii (4 segmente) este acelaşi ca la terminarea normală

3 Resetarea conexiunii

Există situaţii icircn care TCP doreşte resetarea conexiunii De exemplu dacă se solicită iniţierea

unei conexiuni la un port inexistent Icircn acest caz cealaltă parte va trimite un segment cu bitul

RST setat pentru a anula solicitarea O altă situaţie este atunci cacircnd se constată că celalalt capăt

al conexiunii nu răspunde un anumit timp (timeout)

Diagrama de stări

Toate evenimentele ce au loc icircn timpul stabilirii conexiunii transferului şi icircnchiderii conexiunii

pot fi rezumate printr-un automat finit cunoscut sub numele de diagrama de stări După cum

chiar numele sugerează este o maşină cu un număr limitat de stări O stare este păstrată pacircnă icircn

momentul apariţiei unui eveniment moment icircn care se poate trece icircn altă stare şisau efectua o

acţiune

Aceste stări posibile sunt (denumirile sunt asemănătoare cu cele utilizate de netstat) cele din

tabelul 71

Tabela Stările diagramei de stări TCP

Stare Descriere

CLOSED Nu există conexiune

LISTEN Serverul aşteaptă cereri de la clienţi

SYN_SENT Cerere de iniţiere (activă) a conexiunii Se

aşteaptă confirmarea

SYN_RCVD S-a primit o cerere de iniţiere conexiune

ESTABLISHED S-a stabilit conexiunea

FIN_WAIT_1 Aplicaţia a solicitat icircnchiderea conexiunii

FIN_WAIT_2 Serverul a acceptat icircnchiderea conexiunii

CLOSING Ambele părţi solicită simultan icircnchiderea

conexiunii

TIME_WAIT Conexiune icircnchisă dar se aşteaptă ca

pachetele retransmise să dispară

CLOSE_WAIT Serverul aşteaptă icircnchiderea dinspre partea

aplicaţiei

LAST_ACK Serverul a icircnchis conexiunea Aşteaptă

ultima confirmare

Icircn diagrama ilustrată icircn figura 74 putem observa 3 tipuri de tranziţii icircntre cele 11 stări tranziţii

ce corespund unei funcţionări normale pentru client (linii normale continue) pentru server (linii

normale icircntrerupte) şi tranziţii pentru situaţii nestandard (linii subţiri continue)

O comportarea normală pentru client presupune parcurgerea următoarelor stări CLOSED

SYN_SEND ESTABLISHED FIN_WAY_1 FIN_WAY_2 TIME_WAIT

Iniţial clientul TCP se află icircn starea CLOSED

Aşteptacircnd icircn starea CLOSED clientul poate primi de la aplicaţie o cerere de iniţiere

activă a unei conexiuni Trimite un segment SYN şi trece icircn starea SYN_SENT

Icircn starea SYN_SENT clientul aşteaptă de la server un segment ACK+SYN după care

trimite un ACK şi trece icircn starea ESTABLISHED Din acest moment poate icircncepe

transferul efectiv de date Clientul va rămacircne icircn această stare cacirct timp are de trimisprimit

date

Aflat icircn această stare clientul TCP poate primi din partea aplicaţiei o cerere de icircnchidere a

conexiunii Icircn acest caz va trimit un segment FIN şi trece icircn starea FIN_WAIT_1

Icircn această stare clientul aşteaptă ACK din partea serverului După ce-l primeşte

conexiunea icircntr-un sens se va icircnchide şi clientul trece icircn starea FIN_WAIT_2

Starea FIN_WAIT_2 durează pacircnă cacircnd primeşte cererea de icircnchidere a conexiunii FIN

din partea serverului Trimite ACK şi va trece icircn starea TIME_WAIT

Icircn această stare se va porni un timer cu valoarea setată la dublul timpului de viaţă estimat

pentru un segment de lungime maximă MSL (Maximum Segment Lifetime) Acest timer

permite retransmiterea ACK-ului icircn cazul icircn care acesta se pierde (celălalt capăt va da

timeout şi va retransmite segmentul FIN) Icircn tot acest time cei doi sockeţi (de la client şi

server) nu vor putea fi reutilizaţi Totodată pachetele icircntacircrziate care sosesc icircn această

perioadă sunt ignorate După expirarea acestui timer clientul revine icircn starea iniţială

CLOSED

Din punctul de vedere al unui server o comportare standard parcurge următoarele stări

CLOSED LISTEN SYN_RCVD ESTABLISHED CLOSE_WAIT şi LAST_ACK

Iniţial serverul TCP se află icircn starea CLOSED

Icircn această stare poate primi de la aplicaţia server o cerere de iniţiere activă şi trece icircn

starea LISTEN

Aflat icircn starea LISTEN serverului TCP poate recepţiona un segment SYN de la un client

TCP Icircn acest caz va trimite ACK+SYN şi va trece icircn starea SYN_RCVD

Icircn această stare serverul aşteaptă primirea confirmării de la client moment icircn care

conexiunea e stabilită icircn ambele sensuri şi se poate icircncepe transferul de date (starea

ESTABLISHED)

Clientul TCP poate solicita icircnchiderea conexiunii trimiţacircnd un segment FIN către server

Icircn acest caz serverul TCP trimite confirmarea şi trece icircn starea CLOSE_WAIT

Icircn această stare serverul aşteaptă să primească din partea programului server icircnchiderea

conexiunii moment icircn care va trimite către client un segment FIN şi trece icircn starea

LAST_ACK

Serverul aşteaptă primirea ultimei confirmări de la client după care revine icircn starea

CLOSED

Atacirct serverul cacirct şi clientul TCP se pot afla icircn oricare din cele 11 stări ale diagramei

Figura Diagrama de stări pentru TCP

4 Controlul fluxului

Dacă icircncă de la icircnceput s-a reuşit stabilirea formatului unui pachet TCP şi a modulului icircn care

trebuie să se facă icircnchiderea şi deschiderea unei conexiuni nu acelaşi lucru se poate spune şi

despre modul icircn care ar trebui să se realizeze controlul fluxului Ţinacircnd seama icircnsă că din 1989

(de cacircnd datează RFC-ul 2581 cel despre care am menţionat că specifică icircn mod clar modul icircn

care trebuie să se comporte o implementare de TCP) TCP-ul a rămas neschimbat putem să icircl

considerăm un rezultat important al domeniului reţelor de calculatoare

Icircn cele ce urmează vom icircnţelege prin controlul fluxului totalitatea algoritmilor care permit

atingerea unei viteze de transfer punct-la-punct cacirct mai mare pentru toate conexiunile existente

Icircn principal aceşti algoritmi stabilesc modul icircn care segmentele şi confirmările trebuie trimise şi

ce acţiuni trebuie executate icircn situaţiile icircn care răspunsurile aşteptate de la celălalt capăt icircntacircrzie

să vină

Subsections

Icircntacircrzierea confirmărilor

Algoritmul Nagle

Fereastra glisantă

Slow start

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Evitarea congestiei

Fast Retransmission Fast Recovery

Sindromul ``Silly Window

TCP Keepalive Timer

Icircntacircrzierea confirmărilor

O modalitate simplă de generare a confirmărilor este de a trimite cacircte una pentru fiecare segment

primit Această politică prezintă avantajul de a face comunicaţia self-clocking icircnsă este

ineficientă dacă segmentele care nu conţin decacirct confirmări sunt urmate la scurtă distanţă (cacircteva

zeci de milisecunde) de segmente ce conţin date efective Pentru a evita această situaţie se

procedează2 la icircntacircrzierea (200ms este o valoare uzuală icircn RFC 1122 se specifică o valoare

maximă de 500ms) a segmentelor care conţin doar confirmări Această strategie face posibil ca

un răspuns generat de primirea unor date să plece sper celălalt capăt icircn acelaşi segment cu

confirmarea

Observaţie deoarece este dificil de menţinut timere pentru fiecare confirmare diferenţa de

200ms este calculată de un timer global Din acest motiv modul efectiv de comportare poate fi

descris şi icircn felul următor cacircnd un segment nu conţine decacirct o confirmare el este pus icircntr-o

coadă ce va fi inspectată de un proces care din 200 icircn 200 ms trimite tot ce s-a acumulat icircn

coada

Footnotes

2

Acest comportament a fost propus de David D Clark icircn iulie 1982 icircn RFC 813

Algoritmul Nagle

Acest algoritm3 icircncearcă să icircmbunătăţească performanţele exploatacircnd următoarea caracteristică

foarte des icircntacirclnită icircn dialogul dintre două staţii dacă se icircncearcă trimiterea unor date de

dimensiune mică icircnsă există icircncă date neconfirmate de partener atunci ele sunt buffer-ate şi

trimise icircntr-un segment mai mare cacircnd soseşte confirmarea aşteptată Icircn acest fel se poate evita

generarea datagramelor mici (tinygrame) icircn situaţia unei legături lente Icircn cazul unei legături

rapide confirmările vor veni repede şi icircntacircrzierea introdusă de algoritm va neglijabilă

Există icircnsă şi cazuri icircn care acest algoritm duce la deprecierea performanţelor mesajele scurte

generate de mişcările mouse-ului icircn cazul folosirii unui server X Window sau utilizarea tastelor

care trimit mai mult de un caracter (secvenţe escape) Pentru a rezolva aceste inconveninte API-

ul de utilizare a TCP-ului trebuie să ofere o modalitate de a dezactiva acest algoritm (icircn sistemele

bazate pe sockeţi există icircn acest scop opţiunea TCP_NODELAY)

Footnotes

algoritm3

Algoritmul aparţinacircnd lui John Nagle a fost propus icircn ianuarie 1984 icircn RFC 896

Fereastra glisantă

Algoritmul implementat de TCP pentru a implementa transferul sigur de date este cunoscut icircn

teorie sub numele de Go-Back-N Icircn acest algoritm se utilizează numere de secvenţă pentru a

distinge pachetele icircntre ele şi o coadă (dimensiunea maximă a cozii reprezintă fereastra) de

pachetele a căror confirmare se aşteaptă Pachetele se icircmpart icircn 4 categorii

1 pachete trimis şi pentru care s-a primit confirmare

2 pachete trimise şi pentru care se aşteaptă icircncă confirmarea

3 pachete care nu au fost trimise icircncă dar care nu depăşesc limitele ferestrei şi deci pot fi

trimise

4 pachete care icircncă nu au fost trimite şi care nici nu vor putea fi trimise decacirct după ce au

fost trimise toate pachetele din categoria 3 şi s-au primit o parte din confirmările la

pachetele din categoria 2

Dacă confirmările pentru pachetele din categoria 2 icircntacircrzie prea mult (un mecanism de timer-e

informează asupra acestui lucru) atunci ele vor fi retrimise Icircn versiunea iniţială TCP-ul nu

permitea decacirct confirmări pozitive ceea ce icircnseamnă că avansarea ferestrei se va icircmpotmoli la

segmentele neconfirmate Cum se poate evita aceasta situaţie vom discuta icircn detaliu icircn capitolele

următoare O soluţie foarte radicală o constituie introducerea de confirmări selective (acest lucru

este realizat de RFC 2018 din octombrie 1996) Această modifică face ca TCP-ul actual să fie un

hibrid de Go-Back-N şi Selective Repeat

Deoarece dimensiunea ferestrei este anunţată la fiecare segment un client lent poate ca pe măsură

ce trimite confirmările să informeze despre progresul icircnregistrat la livrarea datelor următorului

nivel (aplicaţie) Dacă datele vin prea repede pentru viteza cu care clientul procesează datele

fereastra fereastra se va dimiua şi chiar icircnchide (acest lucru se realizează anunţacircnd o fereastră de

dimensiune zero) Cum se realizează efectiv redeschiderea vom analiza icircntr-un capitol viitor

Slow start

Un transfer de date TCP poate să icircnceapă prin transmiterea de segmente pacircnă la umplerea

icircntregii ferestre după care fie se primesc confirmări care vor permite unor noi pachete să fie

trimise fie vor expira timer-ele de retransmisie şi se va icircncepe retrimiterea pachetelor de la

icircnceputul ferestrei Din păcate un astfel de comportament poate duce la pomparea icircn reţea a unui

număr de pachete prea mare pentru capacitatea disponibilă efectiv icircnrăutăţind congestia Pentru

a evita acest lucru s-a propus următoarea soluţie4 iniţial se trimite un segment după primirea

confirmării lui se trimit două segmente după sosirea confirmărilor pentru ele se trimit patru

segmente şi aşa mai departe La un moment dat fie vor icircncepe să se piardă segmente (un indiciu

că s-a atins capacitatea maximă a canalului) fie se va umple fereastra pe care o anunţă cel care

primeşte Trebuie să remarcam că datorită creşterii exponenţiale a numărului de segmente se va

atinge destul de repede una din cele două situaţii

Modalitatea efectivă de implementare a acestui algoritm are la bază utilizarea unei ferestre de

congestie (congestion window cwnd) care este iniţializată cu dimensiunea unui segment (cwnd

se calculează icircn octeţi) şi la fiecare pas este dublată fereastra efectivă din cadrul căreia se pot

trimite segmente este dată de minimul dintre ultima fereastra comunicată de partener şi cwnd

Footnotes

soluţie4

Soluţia aparţine lui V Jacobson şi a fost prezentată icircn 1988 la conferinţă ACM

SIGCOMM-88

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Deoarece TCP trebuie să funcţioneze icircn condiţii variate de latenţă modul icircn care se face

retransmiterea trebuie să fie cacirct mai flexibil (şi simplu icircn acelaşi timp pentru a introduce un

overhead cacirct mai mic) Timpul cacirct se aşteaptă venirea unei confirmări (retransmission timeout

RTO) este calculat prin cronometrarea timpului care icirci ia unui segment trimis să fie confirmat

Pentru o anumită conexiune se cronometrează cacircte un singur segment la un moment dat iar pe

baza RTT-ului măsurat se actualizează valoare RTO-ului

Icircn RFC 793 formula de calcul a RTO-ului este următoarea

unde este ultimul RTT măsurat este o estimare ponderată pentru RTT este un coeficient

de ponderare care icircn general are valoarea iar este un coeficient cu o valoare recomandată

de După cum se poate observa icircn valoarea lui este inclusă icircn mare măsură vechea valoarea

Icircn acest fel ajustarea RTT-ului se face treptat Din păcate acest mod de calcul nu funcţionează

bine la variaţii mari ale RTT-ului ducacircnd la creşterea numărului de retransmisii exact atunci

cacircnd fenomenul de congestie icircncepe să apară

Pentru a remedia aceste neajunsuri V Jacobsen a propus icircn 1988 o nouă metodă de calcul o

metodă care ţine seama seamă şi de modul icircn care variază diferenţa dintre RTT-uri Formulele

folosite sunt următoarele

unde este un estimare pentru media RTT-urilor este o estimare pentru abaterea RTT-urilor

faţă de medie (o aproximaţie suficientă pentru abaterea pătratică medie care icircnsă este mult mai

costisitor de calculat) este diferenţa dintre RTT-ul măsurat ( ) şi estimarea curentă ( )

Coeficientul cu care este actualizată estimarea curentă are valoarea de iar cel cu care este

actualizat estimarea abaterii este La stabilirea unei conexiuni valorile pentru şi sunt

alese astfel icircncacirct să rezulte un RTT de secunde şi un de 3 secunde (aceste recomandări

sunt făcute de RFC 1122)

Dacă pentru un anumit segment nu se primeşte confirmarea icircn intervalul indicat de el va fi

retrimis şi noul este dublat Valoarea maximă admisă pentru este de 240 secunde

Deoarece icircn cazul retrimiterilor nu se poate determina cu exactitate căruia din segmentele trimise

aparţine confirmarea actualizarea estimărilor este amacircnată pacircnă cacircnd se reuşeşte trimiterea

corectă (s-a primit confirmare) fără retransmitere(``din prima) a unui segment Acest artificiu

(deloc neimportant) care permite evitarea actualizarea eronată a estimărilor este cunoscut sub

numele de algoritmul lui Karn şi a fost propus icircn 1987 de P Karn şi C Partridge

Evitarea congestiei

Dacă cei doi parteneri care comunică prelucrează datele suficient de repede şi vor să transfere un

volum mare de date atunci limitarea de care se vor lovi este cea dată de viteza reţelei Din cauza

modului ``best-effort pe care IP-ul icircl oferă cacircnd canalul de comunicaţie este saturat o parte din

segmentele TCP se vor pierde Icircn mod poate paradoxal atacirct transmiţătorului cacirct şi receptorul se

pot afla icircn poziţia de a fi primii icircn detectarea pierderii unui segment Unul din indiciile de la

transmiţător care semnalează pierderea unui segment este (icircn mod evident) apariţia 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 icircn varianta iniţială nu

permite decacirct confirmări pozitive singurul lucru pe care receptorul icircl poate face este ca la fiecare

segment out-of-order primit să trimită o confirmare indicacircnd prin aceasta că la el continuă să

vină segmente icircnsă cel indicat de numărul de secvenţă de confirmare lipseşte Primirea acestor

confirmări multiple este al doilea mod icircn care transmiţătorul poate afla de apariţia congestiei

Algoritmul ce trebuie aplicat icircn momentul icircn care se detectează apariţia congestiei este cunoscut

sub numele de ``evitarea congestiei (congestion avoidence) Principiul care stă la baza lui este

ca la apariţia congestiei fie să se treacă la o incrementare liniară a dimensiunii ferestrei dacă

congestia a fost detectată ca urmare a primirii unor confirmări identice repetate fie să se reia

slow start-ul icircn cazul icircn care congestia s-a detectat prin expirarea unui timer de timeout

Implementarea acestui algoritm se bazează pe utilizarea unui nou contor (sstresh) care să indice

dimensiunea ferestrei de la care se trece de la incrementarea exponenţială la cea liniară

Algoritmul efectiv este următorul

1 la stabilirea unei noi conexiuni se pleacă cu sstresh iniţializat la valoare de 64K şi cwnd

la dimensiunea unui segment

2 trimiterea de segmente se face fără a depăşi minimul dintre fereastra publicată de partener

(pentru a nu depăşi capacitatea de procesesare a partenerului) şi cwnd-ul curent (pentru a

nu depăşi limita impusă de capacitatea reţelei)

3 la apariţia congestiei sstresh este setat la jumătatea valorii ferestrei curente (minimul

dintre fereastra anunţată de partener şi cwnd icircnsă cel puţin dimensiunea corespunzătoare

pentru două segmente) dacă congestia a fost detectată prin expirarea unui timer de

timeout atunci cwnd este iniţializat cu dimensiunea unui segment

4 la primirea unei confirmări incrementarea se face icircn două moduri icircn funcţie de relaţie icircn

care se află cwnd şi sstresh

1 dacă cwnd e mai mic sau egal cu sstresh se face incrementarea exponenţială

caracteristică slow start-ului (care de fapt nu e deloc slow icircn cazul de faţă)

2 dacă cwnd e mai mare ca sstresh atunci se face o incrementare cu dimensiunea

unui segment

Fast Retransmission Fast Recovery

După cum am văzut un receptor care primeşte segmente out-of-order va trimite transmiţătorului

confirmări duplicate Algoritmul denumit ``fast retransmission recomandă următoarele două

comportamenet

1 un receptor care detectează segmente out-of order trebuie să nu icircntacircrzie trimiterea de

confirmări (după cum am văzut icircn general confimările sunt icircntacircrziate micşora numărul de

pachete fără date care sunt transferate)

2 un transmiţător care care primeşte mai mult de trei confirmări duplicate trebuie să

retrimită segmentul indicat ca fiind neprimit de confirmările icircn cauză fără a aştepta

expirarea timer-ul de timeout

Algoritmul de ``fast recovery icircncearcă să optimizeze şi mai mult comportamentul

transmiţătorului care detectează un număr de trei sau mai multe confimări duplicate Mai exact el

recomandă trecerea la actualizarea liniară a ferestrei (congestion avoidance) Acest tip de

comportament se poate justifica prin următorul raţionament deoarece icircncă mai sunt transferate

date icircntre cei doi parteneri (şi acest lucru se icircntacircmplă sigur de vreme ce sosesc confirmări

duplicate icircn cazul acesta) icircnseamnă că transferul nu este afectat de o congestie severă şi prin

urmare trecerea la slow start nu e (icircncă) necesară (slow start-ul eliberează aproape complet

canalul deoarece cwnd este resetat la dimensiunea unui singur segment)

Cei doi algoritmi pot fi implementaţi icircn felul următor

1 cacircnd se detectează trei confirmări consecutive identice se setează sstresh la jumătate din

valoarea cwnd se retransmite segmentul care s-a pierdut şi se setează cwnd la valoarea

egală cu sstresh plus dimensiunea a trei segmente (acest lucru va face ca algoritmul de

incrementare a cwnd să treacă la incrementare liniară)

2 la fiecare confirmare duplicată care mai soseşte se incrementează cwnd se incrementează

cu dimensiunea unui segment

3 cacircnd icircncetează primirea de confirmări duplicate (segmentul retrimis a ajuns cu bine la

receptor şi s-a trimis o confirmare care acoperă segmentul care se pierduse iniţial) cwnd

este setat la valoarea sstresh

Sindromul ``Silly Window

Protocoalele bazate pe fereastră glisantă (cum este şi TCP-ul) pot să ajungă icircn situaţia deloc

fericită de trimite un număr mare de segmente mici icircn loc de segmente de dimensiune maximă

Acest tip de comportament este cunoscut sub numele de sindromul ``silly window

O modalitate prin care TCP-ul poate să cadă victimă acestui tip de comportament este

deschiderea de ferestre cu dimensiune foarte mică O altă situaţia nefericită este cea icircn care un

transmiţător este ``lacom şi trimite date indiferent de cacirct de mică este fereastra (după cum vom

vedea imediat uneori are sens şi un astfel de comportament) Algoritmul de evitare a acestor

neajunsuri este următorul

1 un receptor nu trebuie să anunţe deschideri de ferestre mici Mai exact nu se recomandă

anunţarea unei incrementări a ferestrei mai mică decacirct dimensiunea unui segment (MSS)

sau jumătate din buffer-ul aflat la dispoziţia receptorului oricare din ele e mai mică

2 un transmiţător va trimite date doar icircn următoarele cazuri

1 se poate trimite un segment icircntreg

2 se poate trimite jumătate din dimensiunea celei mai mari ferestre pe care

partenerul a publicat-o pacircnă acum

3 toate datele trimise pacircnă acum au fost confirmate sau algoritmul Nagle este

dezactivat şi se trimit toate datele care sunt icircn buffer-ul de trimitere

Cacircteva justificări cazul 2b tratează cazul icircn care partenerul anunţă ferestre mai mici decacirct

dimensiunea unui segment iar cazul 2c impune condiţiile respectării algoritmului Nagle după

cum se vede dacă algoritmul Nagle este activ şi s-au acumulat destul date mai exact cacirct

dimensiunea unui segment el va fi trimis chiar dacă există segmente neconfirmate Pentru

implementarea comportamentului impus de 2b un transmiţător trebuie să ţină evidenţa celei mai

mari ferestre pe care partenerul a anunţat-o Ţinacircnd seama că dimensiunea acestor buffer-e nu se

modifică acest mod de a icircncerca determinarea lor este suficient

O altă problemă legată tot de ferestre este cazul icircnchiderii acesteia Un mod icircn care s-ar putea

anunţa redeschiderea este trimiterea de către receptor a unei confirmări (duplicat) care să anunţe

redeschiderea la o anumită valoare a ferestrei Deoarece acest pachet nu trebuie confirmat icircn mod

special şi s-ar putea să se piardă se poate ajunge icircn situaţia icircn care receptorul a anunţat

redeschiderea ferestrei segmentul s-a pierdut iar transmiţătorul icircncă mai icircl mai aşteaptă pentru a

putea continua transferul Rezolvarea la această problemă s-a făcut prin impunerea unui alt

comportament

1 transmiţătorul va trimite segmente cu dimensiunea datelor de un octet prin care sondează

deschiderea ferestrei intervalul la care se sondează redeschiderea ferestrei se dublează

(exponenţial backoff) icircn RFC 793 dimensiunea maximă recomandată este de 2 minute

icircnsă icircn RFC 1122 se specifică că maximul este acelaşi cu cel din cazul retransmisiei (240

secunde)

2 receptorul trebuie să refuze aceste pachete răspunzacircnd cu segmente de confirmare care

indică neprimirea octetului respectiv

Observaţie timer-ul special necesar pentru implementare la transmiţător a comportamentului de mai sus este cunoscut sub numele de ``TCP Persistent Timer Numele este justificat de faptul că sondarea deschiderii se va face pacircnă cacircnd fie fereastra se deschide fie conexiunea se icircntrerupe TCP Keepalive Timer

Un lucru interesant despre TCP este faptul că dacă nivelele superioare nu comunică nimic icircntre

ele pentru o perioadă lungă 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 icircn care au trecut cu succes de faza stabilirii legăturii Dacă nivelurile

inferioare (reţeaIP fizic) devin temporar indisponibile cacirct tip cei doi nu vor să comunice atunci

acest lucru nu va perturba icircn nici un fel activitatea şi acest lucru este acceptabil Problemele

icircncep să apară icircn momentul icircn care cei doi doresc să comunice şi nivelele inferioare nu mai

permit acest lucru Evident că cel care va dori să comunice ceva va detecta icircntreruperea legăturii

şi va icircnchide conexiunea Ce se icircntacircmplă icircnsă dacă celălalt capăt nu are nimic de comunicat (de

exemplu este un server care oferă anumite servicii) Pentru el legătura va fi icircn continuare activă

şi icircn general anumite resurse vor fi rezervate pentru aceasta Rezolvarea acestei situaţii este dată

de introducerea unei mecanism de sondare a stării legăturii pe baza unui timer (TCP Keepalive

Timer) care se declanşează din două icircn două ore La fiecare expirare a timer-ului se trimite un

segment fără date care confirmă datele primite pacircnă atunci Răspunsul care trebuie primit este tot

un segment fără date care confirmă datele primite de partener (practic o re-publicare a stării celor

doi parteneri) Dacă răspunsul nu este primit timp de 75 secunde atunci segmentul va fi retrimis

Dacă după 10 astfel de icircncercări tot nu s-a primit nici un răspuns atunci conexiunea se va

considera terminată şi se va anunţa nivelul superior asupra acestui lucru

Observaţii

dacă o staţie primeşte segmente de keepalive despre conexiuni care nu mai sunt active

(de exemplu a fost resetat) atunci va răspunde cu segmente de reset (acesta e un procedeu

standard)

RFC 1122 specifică că facilitatea de keepalive trebuie activată icircn mod explicit

3 Studii de caz

Subsections

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

1 Fragmentarea pachetelor UDP

Deoarece UDP-ul este un serviciu fără conexiune toate datele pe care le primeşte de la nivelul

superior sunt icircncapsulate icircntr-o singură datagramă UDP care apoi va forma un pachet IP Dacă

pachetul IP astfel obţinut este prea mare atunci mecanismele IP de fragmentare icircl vor sparge icircn

bucăţi Exemplul următor icircncearcă să studieze exact acest fenomen

Pe maşina athos rulează un server de UDP pe portul 50007 Pe o altă maşină frodo aflată icircn

reţeaua locală este rulat un client care poate fi configurat să trimită un pachet UDP de o anumită

lungime Pentru a putea observa ce se icircntacircmplă pe athos este rulat tcpdump

Deoarece MTU-ul pentru o reţea Ethernet este icircn general 1500 şi antetul IP plus cel UDP ocupă

20 + 8 = 28 octeţi o datagramă UDP de dimensiune 1472 ar trebui sa fie trimisă nefragmentată

Pentru siguranţă folosind clientul de pe athos s-a trimis mai icircntacirci o datagramă UDP cu 1471

octeţi de date şi apoi icircncă una cu 1472 Pentru ambele tcpdump a indicat trimiterea lor fără

fragmentare

182556721144 frodonoi33274 gt athosnoi50007 udp 1471 (DF) (ttl 64 id

51481 len 1499)

182559846764 frodonoi33274 gt athosnoi50007 udp 1472 (DF) (ttl 64 id

51793 len 1500)

La o dimensiune de 1473 ar trebui ca trimiterea să genereze două pachete IP unul care să

conţină primii antetul UDP plus primii 1472 octeţi de date şi icircncă un pachet IP care conţine un

singur octet Iată ce indică tcpdump-ul

182605705813 frodonoi gt athosnoi udp (frag 3627411480) (ttl 64 len

21)

182605706116 frodonoi33274 gt athosnoi50007 udp 1473 (frag

3627414800+) (ttl 64 len 1500)

Intr-adevăr au fost generate două pachete IP

primul conţine doar un singur octet de date şi reprezintă ultimul fragment (bitul de more

fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest

lucru) care a fost spartă icircn bucăţi deplasamentul octetului primit in datagrama originală

este 1480

al doilea pachet este primul fragment din datagrama UDP şi conţine antetul UDP (din

cauza asta datele efective ocupă doar 1480 octeţi) deplasamentul este 0 şi bitul de more

fragments este setat (acest lucru este indicat de semnul ``+ de după deplasament)

După cum se poate observa ambele pachete poartă acelaşi număr de identificare (36274) Acest

lucru icircmpreună cu informaţiile date de flag-ul more fragments permite reconstrucţia la

destinaţie a datagramei UDP originale O problemă a acestui mod de fragmentare e că icircn cazul

pierderii unui fragment icircntreaga datagramă va fi compromisă şi va trebui retrimisă icircn icircntregime

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 9: udp tcp

o Sfacircrşit de opţiuni (end of option) - 1 octet

Este utilizat pentru alinierea datelor conţinute icircn cacircmpul de opţiuni Nu poate fi

utilizat decacirct o singură dată marcacircndu-se astfel sfacircrşitul opţiunilor şi icircnceperea

datelor efective Dacă pentru alinierea la un cuvacircnt de 32 de biţi e nevoie de mai

mult de 1 byte se va utiliza opţiunea no operation Orice apare după această

opţiune pacircnă la icircnceputul cuvacircntului următor de 32 de biţi e ignorat

o no operation - 1 octet

Utilizat pentru alinierea la cuvinte de 32 de biţi

o Dimensiunea maximă a segmentului (Maximum Segment Size (MSS)) - 16 biţi

Icircn ciuda denumirii defineşte lungimea maximă a datelor nu dimensiunea

icircntregului segment Poate lua valori icircntre 0 şi 65535 valoarea implicită fiind 536

Această opţiune e valabilă doar icircn pachetele de iniţiere a conexiunii (cele cu flag-

ul SYN setat) fiecare parte făcacircnd cunoscută dimensiunea maximă a datelor

dispusă să le primească icircntr-un pachet Icircn principiu cu cacirct această valoarea e mai

mare e mai bine (deoarece se recuperează din spaţiul ocupat de antetele TCP şi

IP) pacircnă cacircnd apare fragmentarea Valoarea maximă la care se poate seta este

MTU (Maximum Transfer Unit) minus dimensiunea antetului IP şi TCP (1460

octeţi icircn cazul Ethernet)

o Factor de scalare a ferestrei (Window scale factor) - 1 octet

Pentru situaţiile icircn care se doreşte utilizarea unei ferestre mai mare de 65535 bytes

se poate utiliza acest cacircmp pentru mărirea dimensiunii ferestrei Noua dimensiune

va fi Chiar dacă

factorul de scalare poate fi maxim 255 icircn cazul TCPIP el nu poate depăşi

valoarea 16 deoarece dimensiunea maximă a ferestrei nu poate fi mai mare decacirct

valoarea celui mai mare număr de secvenţă ( )

Acest factor se poate seta doar la iniţierea conexiunii Icircn timpul transferului de

date se poate modifica dimensiunea ferestrei dar factorul de scalare rămacircne

acelaşi Dacă cel care a iniţiat conexiunea a trimis icircn segmentul de iniţiere şi acest

factor dar icircn pachetul cu ACK destinatarul nu şi-a trimis şi el factorul atunci se la

considera 0 icircn ambele direcţii Invers dacă cel care solicită deschiderea

conexiunii nu setează factorul destinaţia nu va putea seta factorul de scalare

o Timestamp - 10 octeţi

Utilizat pentru reţinerea timpului icircn vederea calculării RTT (Round Trip Time)

Cacircmpul timestamp e completat de sursă icircn momentul trimiterii segmentului La

destinaţie valoarea este reţinută şi copiată icircn cacircmpul timestamp echo reply al

pachetului cu confirmarea RTT-ul este calculat de sursă făcacircnd diferenţa dintre

timpul curent şi această valoare

Figura Opţiuni TCP

3 Iniţierea şi terminarea unei conexiuni TCP

TCP este un protocol orientat conexiune deci presupune stabilirea unei căi virtuale icircntre sursă şi

destinaţie

Subsections

Protocolul de iniţiere

o 1 Deschiderea simultană

Protocolul de terminare

o 2 Terminarea simultană

o 3 Resetarea conexiunii

Diagrama de stări

Protocolul de iniţiere

Modul de transmisie icircn cazul protocolului TCP este full-duplex deci sunt transmise date

simultan icircn ambele direcţii Aceasta presupune că cel care iniţiază conexiunea trebuie să

primească aprobarea celuilalt capăt icircnainte de icircnceperea transferului de date sursa icircşi anunţă

intenţia de a iniţia o conexiune destinaţia trimite un pachet cu confirmarea cererii şi un pachet de

iniţiere a conexiunii de la el la sursă iar apoi sursa confirmă cererea primită de la destinaţie Paşii

2 şi 3 pot fi realizaţi prin trimiterea unui singur pachet de aceea protocolul de iniţiere este

cunoscut sub numele de three-way handshake

Icircn cadrul protocolului de iniţiere există 2 tipuri de cereri de iniţiere cerere activă (active open)

iniţiată de clientul ce doreşte să stabilească conexiunea cu serverul şi cerere pasivă (passive

open) din partea serverului

Cei 3 paşi sunt

1 Clientul trimite un segment cu flag-ul SYN setat şi care conţine portul sursă portul de la

destinaţie şi numărul de secvenţă generat iniţial (ISN) de la care se vor numerota octeţii

de la client către server Opţional se pot stabili parametrii conexiunii prin setarea lungimii

maxime a segmentelor (MSS) dispus să le primească de la server factorului de scalare a

ferestrei Acest prim segment nu conţine nici un parametru de confirmare şi de asemenea

nu are rost să conţine să seteze dimensiunea ferestrei

2 Al doilea segment e trimis de server şi are un rol dublu confirmă segmentul primit de la

client prin setarea flag-ului ACK şi completează numărul de secvenţă cu numărul de

secvenţă primit plus 1 şi al doilea rol iniţializează conexiunea de la el către client prin

setarea flag-ului SYN şi generarea unui număr de secvenţă iniţial ce va fi folosit icircn

numerotarea octeţilor de la server spre client Pe lacircngă aceasta trebuie să conţină

dimensiunea ferestrei şi opţional poate seta factorul de scalare şi dimensiunea maximă a

segmentului acceptat

3 Clientul trimite un segment cu confirmarea cererii din partea serverului (ACK setat +

completează numărul confirmat cu numărul de secvenţa primit + 1) Ca şi icircn cazul

pasului 2 trebuie să seteze dimensiunea ferestrei Acest pachet poate conţine date

Subsections

1 Deschiderea simultană

1 Deschiderea simultană

Se poate icircntacircmpla ca uneori cele două capete care vor să comunice să icircncerce să stabilească

conexiunea simultan Icircn acest caz după ce fiecare a trimis segmentul de iniţiere (iniţiere activă)

ambele vor trimite un segment cu SYN + ACK şi se va stabili o singură conexiune nu două

Protocolul de terminare

Oricare dintre cele două părţi poate solicita icircnchiderea conexiunii dar conexiunea fiind full-

duplex transferul de date icircn celălalt sens poate continua (această situaţie e denumită half-close)

O icircnchidere completă a unei conexiuni TCP presupune următorii paşi

1 Clientul trimite un segment cu flag-ul FIN activat solicitacircnd icircnchiderea conexiunii

2 Serverul trimite un segment ACK confirmacircnd primirea cererea Numărul de confirmare

se completează normal ca numărul de secvenţă primit + 1

3 Serverul continuă să trimită date către client şi cacircnd doreşte să icircnchidă şi el conexiunea

trimite un segment cu FIN activat

4 Clientul trimite un pachet ACK confirmacircnd icircnchiderea conexiunii

Cel care iniţiază primul procedura de icircnchidere (trimite primul FIN) realizează o icircnchidere activă

(active close) iar celălalt capăt o icircnchidere pasivă (passive close) Icircn mod normal cel care

realizează iniţierea activă va fi primul ce va trimite FIN dar oricare dintre cei doi poate icircnchide

activ conexiunea

Subsections

2 Terminarea simultană

3 Resetarea conexiunii

2 Terminarea simultană

Icircn mod similar cu deschiderea simultană există posibilitatea ca ambele capete ale conexiunii TCP

să iniţieze simultan procedura de icircnchidere a conexiunii Icircn acest caz ambele părţi vor trimite

FIN şi vor aştepta primirea unui ACK Icircn continuare fiecare va primi cererea de terminare şi va

trimite ACK Se observă că numărul de segmente transferate pentru realizarea icircnchiderii

conexiunii (4 segmente) este acelaşi ca la terminarea normală

3 Resetarea conexiunii

Există situaţii icircn care TCP doreşte resetarea conexiunii De exemplu dacă se solicită iniţierea

unei conexiuni la un port inexistent Icircn acest caz cealaltă parte va trimite un segment cu bitul

RST setat pentru a anula solicitarea O altă situaţie este atunci cacircnd se constată că celalalt capăt

al conexiunii nu răspunde un anumit timp (timeout)

Diagrama de stări

Toate evenimentele ce au loc icircn timpul stabilirii conexiunii transferului şi icircnchiderii conexiunii

pot fi rezumate printr-un automat finit cunoscut sub numele de diagrama de stări După cum

chiar numele sugerează este o maşină cu un număr limitat de stări O stare este păstrată pacircnă icircn

momentul apariţiei unui eveniment moment icircn care se poate trece icircn altă stare şisau efectua o

acţiune

Aceste stări posibile sunt (denumirile sunt asemănătoare cu cele utilizate de netstat) cele din

tabelul 71

Tabela Stările diagramei de stări TCP

Stare Descriere

CLOSED Nu există conexiune

LISTEN Serverul aşteaptă cereri de la clienţi

SYN_SENT Cerere de iniţiere (activă) a conexiunii Se

aşteaptă confirmarea

SYN_RCVD S-a primit o cerere de iniţiere conexiune

ESTABLISHED S-a stabilit conexiunea

FIN_WAIT_1 Aplicaţia a solicitat icircnchiderea conexiunii

FIN_WAIT_2 Serverul a acceptat icircnchiderea conexiunii

CLOSING Ambele părţi solicită simultan icircnchiderea

conexiunii

TIME_WAIT Conexiune icircnchisă dar se aşteaptă ca

pachetele retransmise să dispară

CLOSE_WAIT Serverul aşteaptă icircnchiderea dinspre partea

aplicaţiei

LAST_ACK Serverul a icircnchis conexiunea Aşteaptă

ultima confirmare

Icircn diagrama ilustrată icircn figura 74 putem observa 3 tipuri de tranziţii icircntre cele 11 stări tranziţii

ce corespund unei funcţionări normale pentru client (linii normale continue) pentru server (linii

normale icircntrerupte) şi tranziţii pentru situaţii nestandard (linii subţiri continue)

O comportarea normală pentru client presupune parcurgerea următoarelor stări CLOSED

SYN_SEND ESTABLISHED FIN_WAY_1 FIN_WAY_2 TIME_WAIT

Iniţial clientul TCP se află icircn starea CLOSED

Aşteptacircnd icircn starea CLOSED clientul poate primi de la aplicaţie o cerere de iniţiere

activă a unei conexiuni Trimite un segment SYN şi trece icircn starea SYN_SENT

Icircn starea SYN_SENT clientul aşteaptă de la server un segment ACK+SYN după care

trimite un ACK şi trece icircn starea ESTABLISHED Din acest moment poate icircncepe

transferul efectiv de date Clientul va rămacircne icircn această stare cacirct timp are de trimisprimit

date

Aflat icircn această stare clientul TCP poate primi din partea aplicaţiei o cerere de icircnchidere a

conexiunii Icircn acest caz va trimit un segment FIN şi trece icircn starea FIN_WAIT_1

Icircn această stare clientul aşteaptă ACK din partea serverului După ce-l primeşte

conexiunea icircntr-un sens se va icircnchide şi clientul trece icircn starea FIN_WAIT_2

Starea FIN_WAIT_2 durează pacircnă cacircnd primeşte cererea de icircnchidere a conexiunii FIN

din partea serverului Trimite ACK şi va trece icircn starea TIME_WAIT

Icircn această stare se va porni un timer cu valoarea setată la dublul timpului de viaţă estimat

pentru un segment de lungime maximă MSL (Maximum Segment Lifetime) Acest timer

permite retransmiterea ACK-ului icircn cazul icircn care acesta se pierde (celălalt capăt va da

timeout şi va retransmite segmentul FIN) Icircn tot acest time cei doi sockeţi (de la client şi

server) nu vor putea fi reutilizaţi Totodată pachetele icircntacircrziate care sosesc icircn această

perioadă sunt ignorate După expirarea acestui timer clientul revine icircn starea iniţială

CLOSED

Din punctul de vedere al unui server o comportare standard parcurge următoarele stări

CLOSED LISTEN SYN_RCVD ESTABLISHED CLOSE_WAIT şi LAST_ACK

Iniţial serverul TCP se află icircn starea CLOSED

Icircn această stare poate primi de la aplicaţia server o cerere de iniţiere activă şi trece icircn

starea LISTEN

Aflat icircn starea LISTEN serverului TCP poate recepţiona un segment SYN de la un client

TCP Icircn acest caz va trimite ACK+SYN şi va trece icircn starea SYN_RCVD

Icircn această stare serverul aşteaptă primirea confirmării de la client moment icircn care

conexiunea e stabilită icircn ambele sensuri şi se poate icircncepe transferul de date (starea

ESTABLISHED)

Clientul TCP poate solicita icircnchiderea conexiunii trimiţacircnd un segment FIN către server

Icircn acest caz serverul TCP trimite confirmarea şi trece icircn starea CLOSE_WAIT

Icircn această stare serverul aşteaptă să primească din partea programului server icircnchiderea

conexiunii moment icircn care va trimite către client un segment FIN şi trece icircn starea

LAST_ACK

Serverul aşteaptă primirea ultimei confirmări de la client după care revine icircn starea

CLOSED

Atacirct serverul cacirct şi clientul TCP se pot afla icircn oricare din cele 11 stări ale diagramei

Figura Diagrama de stări pentru TCP

4 Controlul fluxului

Dacă icircncă de la icircnceput s-a reuşit stabilirea formatului unui pachet TCP şi a modulului icircn care

trebuie să se facă icircnchiderea şi deschiderea unei conexiuni nu acelaşi lucru se poate spune şi

despre modul icircn care ar trebui să se realizeze controlul fluxului Ţinacircnd seama icircnsă că din 1989

(de cacircnd datează RFC-ul 2581 cel despre care am menţionat că specifică icircn mod clar modul icircn

care trebuie să se comporte o implementare de TCP) TCP-ul a rămas neschimbat putem să icircl

considerăm un rezultat important al domeniului reţelor de calculatoare

Icircn cele ce urmează vom icircnţelege prin controlul fluxului totalitatea algoritmilor care permit

atingerea unei viteze de transfer punct-la-punct cacirct mai mare pentru toate conexiunile existente

Icircn principal aceşti algoritmi stabilesc modul icircn care segmentele şi confirmările trebuie trimise şi

ce acţiuni trebuie executate icircn situaţiile icircn care răspunsurile aşteptate de la celălalt capăt icircntacircrzie

să vină

Subsections

Icircntacircrzierea confirmărilor

Algoritmul Nagle

Fereastra glisantă

Slow start

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Evitarea congestiei

Fast Retransmission Fast Recovery

Sindromul ``Silly Window

TCP Keepalive Timer

Icircntacircrzierea confirmărilor

O modalitate simplă de generare a confirmărilor este de a trimite cacircte una pentru fiecare segment

primit Această politică prezintă avantajul de a face comunicaţia self-clocking icircnsă este

ineficientă dacă segmentele care nu conţin decacirct confirmări sunt urmate la scurtă distanţă (cacircteva

zeci de milisecunde) de segmente ce conţin date efective Pentru a evita această situaţie se

procedează2 la icircntacircrzierea (200ms este o valoare uzuală icircn RFC 1122 se specifică o valoare

maximă de 500ms) a segmentelor care conţin doar confirmări Această strategie face posibil ca

un răspuns generat de primirea unor date să plece sper celălalt capăt icircn acelaşi segment cu

confirmarea

Observaţie deoarece este dificil de menţinut timere pentru fiecare confirmare diferenţa de

200ms este calculată de un timer global Din acest motiv modul efectiv de comportare poate fi

descris şi icircn felul următor cacircnd un segment nu conţine decacirct o confirmare el este pus icircntr-o

coadă ce va fi inspectată de un proces care din 200 icircn 200 ms trimite tot ce s-a acumulat icircn

coada

Footnotes

2

Acest comportament a fost propus de David D Clark icircn iulie 1982 icircn RFC 813

Algoritmul Nagle

Acest algoritm3 icircncearcă să icircmbunătăţească performanţele exploatacircnd următoarea caracteristică

foarte des icircntacirclnită icircn dialogul dintre două staţii dacă se icircncearcă trimiterea unor date de

dimensiune mică icircnsă există icircncă date neconfirmate de partener atunci ele sunt buffer-ate şi

trimise icircntr-un segment mai mare cacircnd soseşte confirmarea aşteptată Icircn acest fel se poate evita

generarea datagramelor mici (tinygrame) icircn situaţia unei legături lente Icircn cazul unei legături

rapide confirmările vor veni repede şi icircntacircrzierea introdusă de algoritm va neglijabilă

Există icircnsă şi cazuri icircn care acest algoritm duce la deprecierea performanţelor mesajele scurte

generate de mişcările mouse-ului icircn cazul folosirii unui server X Window sau utilizarea tastelor

care trimit mai mult de un caracter (secvenţe escape) Pentru a rezolva aceste inconveninte API-

ul de utilizare a TCP-ului trebuie să ofere o modalitate de a dezactiva acest algoritm (icircn sistemele

bazate pe sockeţi există icircn acest scop opţiunea TCP_NODELAY)

Footnotes

algoritm3

Algoritmul aparţinacircnd lui John Nagle a fost propus icircn ianuarie 1984 icircn RFC 896

Fereastra glisantă

Algoritmul implementat de TCP pentru a implementa transferul sigur de date este cunoscut icircn

teorie sub numele de Go-Back-N Icircn acest algoritm se utilizează numere de secvenţă pentru a

distinge pachetele icircntre ele şi o coadă (dimensiunea maximă a cozii reprezintă fereastra) de

pachetele a căror confirmare se aşteaptă Pachetele se icircmpart icircn 4 categorii

1 pachete trimis şi pentru care s-a primit confirmare

2 pachete trimise şi pentru care se aşteaptă icircncă confirmarea

3 pachete care nu au fost trimise icircncă dar care nu depăşesc limitele ferestrei şi deci pot fi

trimise

4 pachete care icircncă nu au fost trimite şi care nici nu vor putea fi trimise decacirct după ce au

fost trimise toate pachetele din categoria 3 şi s-au primit o parte din confirmările la

pachetele din categoria 2

Dacă confirmările pentru pachetele din categoria 2 icircntacircrzie prea mult (un mecanism de timer-e

informează asupra acestui lucru) atunci ele vor fi retrimise Icircn versiunea iniţială TCP-ul nu

permitea decacirct confirmări pozitive ceea ce icircnseamnă că avansarea ferestrei se va icircmpotmoli la

segmentele neconfirmate Cum se poate evita aceasta situaţie vom discuta icircn detaliu icircn capitolele

următoare O soluţie foarte radicală o constituie introducerea de confirmări selective (acest lucru

este realizat de RFC 2018 din octombrie 1996) Această modifică face ca TCP-ul actual să fie un

hibrid de Go-Back-N şi Selective Repeat

Deoarece dimensiunea ferestrei este anunţată la fiecare segment un client lent poate ca pe măsură

ce trimite confirmările să informeze despre progresul icircnregistrat la livrarea datelor următorului

nivel (aplicaţie) Dacă datele vin prea repede pentru viteza cu care clientul procesează datele

fereastra fereastra se va dimiua şi chiar icircnchide (acest lucru se realizează anunţacircnd o fereastră de

dimensiune zero) Cum se realizează efectiv redeschiderea vom analiza icircntr-un capitol viitor

Slow start

Un transfer de date TCP poate să icircnceapă prin transmiterea de segmente pacircnă la umplerea

icircntregii ferestre după care fie se primesc confirmări care vor permite unor noi pachete să fie

trimise fie vor expira timer-ele de retransmisie şi se va icircncepe retrimiterea pachetelor de la

icircnceputul ferestrei Din păcate un astfel de comportament poate duce la pomparea icircn reţea a unui

număr de pachete prea mare pentru capacitatea disponibilă efectiv icircnrăutăţind congestia Pentru

a evita acest lucru s-a propus următoarea soluţie4 iniţial se trimite un segment după primirea

confirmării lui se trimit două segmente după sosirea confirmărilor pentru ele se trimit patru

segmente şi aşa mai departe La un moment dat fie vor icircncepe să se piardă segmente (un indiciu

că s-a atins capacitatea maximă a canalului) fie se va umple fereastra pe care o anunţă cel care

primeşte Trebuie să remarcam că datorită creşterii exponenţiale a numărului de segmente se va

atinge destul de repede una din cele două situaţii

Modalitatea efectivă de implementare a acestui algoritm are la bază utilizarea unei ferestre de

congestie (congestion window cwnd) care este iniţializată cu dimensiunea unui segment (cwnd

se calculează icircn octeţi) şi la fiecare pas este dublată fereastra efectivă din cadrul căreia se pot

trimite segmente este dată de minimul dintre ultima fereastra comunicată de partener şi cwnd

Footnotes

soluţie4

Soluţia aparţine lui V Jacobson şi a fost prezentată icircn 1988 la conferinţă ACM

SIGCOMM-88

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Deoarece TCP trebuie să funcţioneze icircn condiţii variate de latenţă modul icircn care se face

retransmiterea trebuie să fie cacirct mai flexibil (şi simplu icircn acelaşi timp pentru a introduce un

overhead cacirct mai mic) Timpul cacirct se aşteaptă venirea unei confirmări (retransmission timeout

RTO) este calculat prin cronometrarea timpului care icirci ia unui segment trimis să fie confirmat

Pentru o anumită conexiune se cronometrează cacircte un singur segment la un moment dat iar pe

baza RTT-ului măsurat se actualizează valoare RTO-ului

Icircn RFC 793 formula de calcul a RTO-ului este următoarea

unde este ultimul RTT măsurat este o estimare ponderată pentru RTT este un coeficient

de ponderare care icircn general are valoarea iar este un coeficient cu o valoare recomandată

de După cum se poate observa icircn valoarea lui este inclusă icircn mare măsură vechea valoarea

Icircn acest fel ajustarea RTT-ului se face treptat Din păcate acest mod de calcul nu funcţionează

bine la variaţii mari ale RTT-ului ducacircnd la creşterea numărului de retransmisii exact atunci

cacircnd fenomenul de congestie icircncepe să apară

Pentru a remedia aceste neajunsuri V Jacobsen a propus icircn 1988 o nouă metodă de calcul o

metodă care ţine seama seamă şi de modul icircn care variază diferenţa dintre RTT-uri Formulele

folosite sunt următoarele

unde este un estimare pentru media RTT-urilor este o estimare pentru abaterea RTT-urilor

faţă de medie (o aproximaţie suficientă pentru abaterea pătratică medie care icircnsă este mult mai

costisitor de calculat) este diferenţa dintre RTT-ul măsurat ( ) şi estimarea curentă ( )

Coeficientul cu care este actualizată estimarea curentă are valoarea de iar cel cu care este

actualizat estimarea abaterii este La stabilirea unei conexiuni valorile pentru şi sunt

alese astfel icircncacirct să rezulte un RTT de secunde şi un de 3 secunde (aceste recomandări

sunt făcute de RFC 1122)

Dacă pentru un anumit segment nu se primeşte confirmarea icircn intervalul indicat de el va fi

retrimis şi noul este dublat Valoarea maximă admisă pentru este de 240 secunde

Deoarece icircn cazul retrimiterilor nu se poate determina cu exactitate căruia din segmentele trimise

aparţine confirmarea actualizarea estimărilor este amacircnată pacircnă cacircnd se reuşeşte trimiterea

corectă (s-a primit confirmare) fără retransmitere(``din prima) a unui segment Acest artificiu

(deloc neimportant) care permite evitarea actualizarea eronată a estimărilor este cunoscut sub

numele de algoritmul lui Karn şi a fost propus icircn 1987 de P Karn şi C Partridge

Evitarea congestiei

Dacă cei doi parteneri care comunică prelucrează datele suficient de repede şi vor să transfere un

volum mare de date atunci limitarea de care se vor lovi este cea dată de viteza reţelei Din cauza

modului ``best-effort pe care IP-ul icircl oferă cacircnd canalul de comunicaţie este saturat o parte din

segmentele TCP se vor pierde Icircn mod poate paradoxal atacirct transmiţătorului cacirct şi receptorul se

pot afla icircn poziţia de a fi primii icircn detectarea pierderii unui segment Unul din indiciile de la

transmiţător care semnalează pierderea unui segment este (icircn mod evident) apariţia 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 icircn varianta iniţială nu

permite decacirct confirmări pozitive singurul lucru pe care receptorul icircl poate face este ca la fiecare

segment out-of-order primit să trimită o confirmare indicacircnd prin aceasta că la el continuă să

vină segmente icircnsă cel indicat de numărul de secvenţă de confirmare lipseşte Primirea acestor

confirmări multiple este al doilea mod icircn care transmiţătorul poate afla de apariţia congestiei

Algoritmul ce trebuie aplicat icircn momentul icircn care se detectează apariţia congestiei este cunoscut

sub numele de ``evitarea congestiei (congestion avoidence) Principiul care stă la baza lui este

ca la apariţia congestiei fie să se treacă la o incrementare liniară a dimensiunii ferestrei dacă

congestia a fost detectată ca urmare a primirii unor confirmări identice repetate fie să se reia

slow start-ul icircn cazul icircn care congestia s-a detectat prin expirarea unui timer de timeout

Implementarea acestui algoritm se bazează pe utilizarea unui nou contor (sstresh) care să indice

dimensiunea ferestrei de la care se trece de la incrementarea exponenţială la cea liniară

Algoritmul efectiv este următorul

1 la stabilirea unei noi conexiuni se pleacă cu sstresh iniţializat la valoare de 64K şi cwnd

la dimensiunea unui segment

2 trimiterea de segmente se face fără a depăşi minimul dintre fereastra publicată de partener

(pentru a nu depăşi capacitatea de procesesare a partenerului) şi cwnd-ul curent (pentru a

nu depăşi limita impusă de capacitatea reţelei)

3 la apariţia congestiei sstresh este setat la jumătatea valorii ferestrei curente (minimul

dintre fereastra anunţată de partener şi cwnd icircnsă cel puţin dimensiunea corespunzătoare

pentru două segmente) dacă congestia a fost detectată prin expirarea unui timer de

timeout atunci cwnd este iniţializat cu dimensiunea unui segment

4 la primirea unei confirmări incrementarea se face icircn două moduri icircn funcţie de relaţie icircn

care se află cwnd şi sstresh

1 dacă cwnd e mai mic sau egal cu sstresh se face incrementarea exponenţială

caracteristică slow start-ului (care de fapt nu e deloc slow icircn cazul de faţă)

2 dacă cwnd e mai mare ca sstresh atunci se face o incrementare cu dimensiunea

unui segment

Fast Retransmission Fast Recovery

După cum am văzut un receptor care primeşte segmente out-of-order va trimite transmiţătorului

confirmări duplicate Algoritmul denumit ``fast retransmission recomandă următoarele două

comportamenet

1 un receptor care detectează segmente out-of order trebuie să nu icircntacircrzie trimiterea de

confirmări (după cum am văzut icircn general confimările sunt icircntacircrziate micşora numărul de

pachete fără date care sunt transferate)

2 un transmiţător care care primeşte mai mult de trei confirmări duplicate trebuie să

retrimită segmentul indicat ca fiind neprimit de confirmările icircn cauză fără a aştepta

expirarea timer-ul de timeout

Algoritmul de ``fast recovery icircncearcă să optimizeze şi mai mult comportamentul

transmiţătorului care detectează un număr de trei sau mai multe confimări duplicate Mai exact el

recomandă trecerea la actualizarea liniară a ferestrei (congestion avoidance) Acest tip de

comportament se poate justifica prin următorul raţionament deoarece icircncă mai sunt transferate

date icircntre cei doi parteneri (şi acest lucru se icircntacircmplă sigur de vreme ce sosesc confirmări

duplicate icircn cazul acesta) icircnseamnă că transferul nu este afectat de o congestie severă şi prin

urmare trecerea la slow start nu e (icircncă) necesară (slow start-ul eliberează aproape complet

canalul deoarece cwnd este resetat la dimensiunea unui singur segment)

Cei doi algoritmi pot fi implementaţi icircn felul următor

1 cacircnd se detectează trei confirmări consecutive identice se setează sstresh la jumătate din

valoarea cwnd se retransmite segmentul care s-a pierdut şi se setează cwnd la valoarea

egală cu sstresh plus dimensiunea a trei segmente (acest lucru va face ca algoritmul de

incrementare a cwnd să treacă la incrementare liniară)

2 la fiecare confirmare duplicată care mai soseşte se incrementează cwnd se incrementează

cu dimensiunea unui segment

3 cacircnd icircncetează primirea de confirmări duplicate (segmentul retrimis a ajuns cu bine la

receptor şi s-a trimis o confirmare care acoperă segmentul care se pierduse iniţial) cwnd

este setat la valoarea sstresh

Sindromul ``Silly Window

Protocoalele bazate pe fereastră glisantă (cum este şi TCP-ul) pot să ajungă icircn situaţia deloc

fericită de trimite un număr mare de segmente mici icircn loc de segmente de dimensiune maximă

Acest tip de comportament este cunoscut sub numele de sindromul ``silly window

O modalitate prin care TCP-ul poate să cadă victimă acestui tip de comportament este

deschiderea de ferestre cu dimensiune foarte mică O altă situaţia nefericită este cea icircn care un

transmiţător este ``lacom şi trimite date indiferent de cacirct de mică este fereastra (după cum vom

vedea imediat uneori are sens şi un astfel de comportament) Algoritmul de evitare a acestor

neajunsuri este următorul

1 un receptor nu trebuie să anunţe deschideri de ferestre mici Mai exact nu se recomandă

anunţarea unei incrementări a ferestrei mai mică decacirct dimensiunea unui segment (MSS)

sau jumătate din buffer-ul aflat la dispoziţia receptorului oricare din ele e mai mică

2 un transmiţător va trimite date doar icircn următoarele cazuri

1 se poate trimite un segment icircntreg

2 se poate trimite jumătate din dimensiunea celei mai mari ferestre pe care

partenerul a publicat-o pacircnă acum

3 toate datele trimise pacircnă acum au fost confirmate sau algoritmul Nagle este

dezactivat şi se trimit toate datele care sunt icircn buffer-ul de trimitere

Cacircteva justificări cazul 2b tratează cazul icircn care partenerul anunţă ferestre mai mici decacirct

dimensiunea unui segment iar cazul 2c impune condiţiile respectării algoritmului Nagle după

cum se vede dacă algoritmul Nagle este activ şi s-au acumulat destul date mai exact cacirct

dimensiunea unui segment el va fi trimis chiar dacă există segmente neconfirmate Pentru

implementarea comportamentului impus de 2b un transmiţător trebuie să ţină evidenţa celei mai

mari ferestre pe care partenerul a anunţat-o Ţinacircnd seama că dimensiunea acestor buffer-e nu se

modifică acest mod de a icircncerca determinarea lor este suficient

O altă problemă legată tot de ferestre este cazul icircnchiderii acesteia Un mod icircn care s-ar putea

anunţa redeschiderea este trimiterea de către receptor a unei confirmări (duplicat) care să anunţe

redeschiderea la o anumită valoare a ferestrei Deoarece acest pachet nu trebuie confirmat icircn mod

special şi s-ar putea să se piardă se poate ajunge icircn situaţia icircn care receptorul a anunţat

redeschiderea ferestrei segmentul s-a pierdut iar transmiţătorul icircncă mai icircl mai aşteaptă pentru a

putea continua transferul Rezolvarea la această problemă s-a făcut prin impunerea unui alt

comportament

1 transmiţătorul va trimite segmente cu dimensiunea datelor de un octet prin care sondează

deschiderea ferestrei intervalul la care se sondează redeschiderea ferestrei se dublează

(exponenţial backoff) icircn RFC 793 dimensiunea maximă recomandată este de 2 minute

icircnsă icircn RFC 1122 se specifică că maximul este acelaşi cu cel din cazul retransmisiei (240

secunde)

2 receptorul trebuie să refuze aceste pachete răspunzacircnd cu segmente de confirmare care

indică neprimirea octetului respectiv

Observaţie timer-ul special necesar pentru implementare la transmiţător a comportamentului de mai sus este cunoscut sub numele de ``TCP Persistent Timer Numele este justificat de faptul că sondarea deschiderii se va face pacircnă cacircnd fie fereastra se deschide fie conexiunea se icircntrerupe TCP Keepalive Timer

Un lucru interesant despre TCP este faptul că dacă nivelele superioare nu comunică nimic icircntre

ele pentru o perioadă lungă 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 icircn care au trecut cu succes de faza stabilirii legăturii Dacă nivelurile

inferioare (reţeaIP fizic) devin temporar indisponibile cacirct tip cei doi nu vor să comunice atunci

acest lucru nu va perturba icircn nici un fel activitatea şi acest lucru este acceptabil Problemele

icircncep să apară icircn momentul icircn care cei doi doresc să comunice şi nivelele inferioare nu mai

permit acest lucru Evident că cel care va dori să comunice ceva va detecta icircntreruperea legăturii

şi va icircnchide conexiunea Ce se icircntacircmplă icircnsă dacă celălalt capăt nu are nimic de comunicat (de

exemplu este un server care oferă anumite servicii) Pentru el legătura va fi icircn continuare activă

şi icircn general anumite resurse vor fi rezervate pentru aceasta Rezolvarea acestei situaţii este dată

de introducerea unei mecanism de sondare a stării legăturii pe baza unui timer (TCP Keepalive

Timer) care se declanşează din două icircn două ore La fiecare expirare a timer-ului se trimite un

segment fără date care confirmă datele primite pacircnă atunci Răspunsul care trebuie primit este tot

un segment fără date care confirmă datele primite de partener (practic o re-publicare a stării celor

doi parteneri) Dacă răspunsul nu este primit timp de 75 secunde atunci segmentul va fi retrimis

Dacă după 10 astfel de icircncercări tot nu s-a primit nici un răspuns atunci conexiunea se va

considera terminată şi se va anunţa nivelul superior asupra acestui lucru

Observaţii

dacă o staţie primeşte segmente de keepalive despre conexiuni care nu mai sunt active

(de exemplu a fost resetat) atunci va răspunde cu segmente de reset (acesta e un procedeu

standard)

RFC 1122 specifică că facilitatea de keepalive trebuie activată icircn mod explicit

3 Studii de caz

Subsections

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

1 Fragmentarea pachetelor UDP

Deoarece UDP-ul este un serviciu fără conexiune toate datele pe care le primeşte de la nivelul

superior sunt icircncapsulate icircntr-o singură datagramă UDP care apoi va forma un pachet IP Dacă

pachetul IP astfel obţinut este prea mare atunci mecanismele IP de fragmentare icircl vor sparge icircn

bucăţi Exemplul următor icircncearcă să studieze exact acest fenomen

Pe maşina athos rulează un server de UDP pe portul 50007 Pe o altă maşină frodo aflată icircn

reţeaua locală este rulat un client care poate fi configurat să trimită un pachet UDP de o anumită

lungime Pentru a putea observa ce se icircntacircmplă pe athos este rulat tcpdump

Deoarece MTU-ul pentru o reţea Ethernet este icircn general 1500 şi antetul IP plus cel UDP ocupă

20 + 8 = 28 octeţi o datagramă UDP de dimensiune 1472 ar trebui sa fie trimisă nefragmentată

Pentru siguranţă folosind clientul de pe athos s-a trimis mai icircntacirci o datagramă UDP cu 1471

octeţi de date şi apoi icircncă una cu 1472 Pentru ambele tcpdump a indicat trimiterea lor fără

fragmentare

182556721144 frodonoi33274 gt athosnoi50007 udp 1471 (DF) (ttl 64 id

51481 len 1499)

182559846764 frodonoi33274 gt athosnoi50007 udp 1472 (DF) (ttl 64 id

51793 len 1500)

La o dimensiune de 1473 ar trebui ca trimiterea să genereze două pachete IP unul care să

conţină primii antetul UDP plus primii 1472 octeţi de date şi icircncă un pachet IP care conţine un

singur octet Iată ce indică tcpdump-ul

182605705813 frodonoi gt athosnoi udp (frag 3627411480) (ttl 64 len

21)

182605706116 frodonoi33274 gt athosnoi50007 udp 1473 (frag

3627414800+) (ttl 64 len 1500)

Intr-adevăr au fost generate două pachete IP

primul conţine doar un singur octet de date şi reprezintă ultimul fragment (bitul de more

fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest

lucru) care a fost spartă icircn bucăţi deplasamentul octetului primit in datagrama originală

este 1480

al doilea pachet este primul fragment din datagrama UDP şi conţine antetul UDP (din

cauza asta datele efective ocupă doar 1480 octeţi) deplasamentul este 0 şi bitul de more

fragments este setat (acest lucru este indicat de semnul ``+ de după deplasament)

După cum se poate observa ambele pachete poartă acelaşi număr de identificare (36274) Acest

lucru icircmpreună cu informaţiile date de flag-ul more fragments permite reconstrucţia la

destinaţie a datagramei UDP originale O problemă a acestui mod de fragmentare e că icircn cazul

pierderii unui fragment icircntreaga datagramă va fi compromisă şi va trebui retrimisă icircn icircntregime

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 10: udp tcp

Figura Opţiuni TCP

3 Iniţierea şi terminarea unei conexiuni TCP

TCP este un protocol orientat conexiune deci presupune stabilirea unei căi virtuale icircntre sursă şi

destinaţie

Subsections

Protocolul de iniţiere

o 1 Deschiderea simultană

Protocolul de terminare

o 2 Terminarea simultană

o 3 Resetarea conexiunii

Diagrama de stări

Protocolul de iniţiere

Modul de transmisie icircn cazul protocolului TCP este full-duplex deci sunt transmise date

simultan icircn ambele direcţii Aceasta presupune că cel care iniţiază conexiunea trebuie să

primească aprobarea celuilalt capăt icircnainte de icircnceperea transferului de date sursa icircşi anunţă

intenţia de a iniţia o conexiune destinaţia trimite un pachet cu confirmarea cererii şi un pachet de

iniţiere a conexiunii de la el la sursă iar apoi sursa confirmă cererea primită de la destinaţie Paşii

2 şi 3 pot fi realizaţi prin trimiterea unui singur pachet de aceea protocolul de iniţiere este

cunoscut sub numele de three-way handshake

Icircn cadrul protocolului de iniţiere există 2 tipuri de cereri de iniţiere cerere activă (active open)

iniţiată de clientul ce doreşte să stabilească conexiunea cu serverul şi cerere pasivă (passive

open) din partea serverului

Cei 3 paşi sunt

1 Clientul trimite un segment cu flag-ul SYN setat şi care conţine portul sursă portul de la

destinaţie şi numărul de secvenţă generat iniţial (ISN) de la care se vor numerota octeţii

de la client către server Opţional se pot stabili parametrii conexiunii prin setarea lungimii

maxime a segmentelor (MSS) dispus să le primească de la server factorului de scalare a

ferestrei Acest prim segment nu conţine nici un parametru de confirmare şi de asemenea

nu are rost să conţine să seteze dimensiunea ferestrei

2 Al doilea segment e trimis de server şi are un rol dublu confirmă segmentul primit de la

client prin setarea flag-ului ACK şi completează numărul de secvenţă cu numărul de

secvenţă primit plus 1 şi al doilea rol iniţializează conexiunea de la el către client prin

setarea flag-ului SYN şi generarea unui număr de secvenţă iniţial ce va fi folosit icircn

numerotarea octeţilor de la server spre client Pe lacircngă aceasta trebuie să conţină

dimensiunea ferestrei şi opţional poate seta factorul de scalare şi dimensiunea maximă a

segmentului acceptat

3 Clientul trimite un segment cu confirmarea cererii din partea serverului (ACK setat +

completează numărul confirmat cu numărul de secvenţa primit + 1) Ca şi icircn cazul

pasului 2 trebuie să seteze dimensiunea ferestrei Acest pachet poate conţine date

Subsections

1 Deschiderea simultană

1 Deschiderea simultană

Se poate icircntacircmpla ca uneori cele două capete care vor să comunice să icircncerce să stabilească

conexiunea simultan Icircn acest caz după ce fiecare a trimis segmentul de iniţiere (iniţiere activă)

ambele vor trimite un segment cu SYN + ACK şi se va stabili o singură conexiune nu două

Protocolul de terminare

Oricare dintre cele două părţi poate solicita icircnchiderea conexiunii dar conexiunea fiind full-

duplex transferul de date icircn celălalt sens poate continua (această situaţie e denumită half-close)

O icircnchidere completă a unei conexiuni TCP presupune următorii paşi

1 Clientul trimite un segment cu flag-ul FIN activat solicitacircnd icircnchiderea conexiunii

2 Serverul trimite un segment ACK confirmacircnd primirea cererea Numărul de confirmare

se completează normal ca numărul de secvenţă primit + 1

3 Serverul continuă să trimită date către client şi cacircnd doreşte să icircnchidă şi el conexiunea

trimite un segment cu FIN activat

4 Clientul trimite un pachet ACK confirmacircnd icircnchiderea conexiunii

Cel care iniţiază primul procedura de icircnchidere (trimite primul FIN) realizează o icircnchidere activă

(active close) iar celălalt capăt o icircnchidere pasivă (passive close) Icircn mod normal cel care

realizează iniţierea activă va fi primul ce va trimite FIN dar oricare dintre cei doi poate icircnchide

activ conexiunea

Subsections

2 Terminarea simultană

3 Resetarea conexiunii

2 Terminarea simultană

Icircn mod similar cu deschiderea simultană există posibilitatea ca ambele capete ale conexiunii TCP

să iniţieze simultan procedura de icircnchidere a conexiunii Icircn acest caz ambele părţi vor trimite

FIN şi vor aştepta primirea unui ACK Icircn continuare fiecare va primi cererea de terminare şi va

trimite ACK Se observă că numărul de segmente transferate pentru realizarea icircnchiderii

conexiunii (4 segmente) este acelaşi ca la terminarea normală

3 Resetarea conexiunii

Există situaţii icircn care TCP doreşte resetarea conexiunii De exemplu dacă se solicită iniţierea

unei conexiuni la un port inexistent Icircn acest caz cealaltă parte va trimite un segment cu bitul

RST setat pentru a anula solicitarea O altă situaţie este atunci cacircnd se constată că celalalt capăt

al conexiunii nu răspunde un anumit timp (timeout)

Diagrama de stări

Toate evenimentele ce au loc icircn timpul stabilirii conexiunii transferului şi icircnchiderii conexiunii

pot fi rezumate printr-un automat finit cunoscut sub numele de diagrama de stări După cum

chiar numele sugerează este o maşină cu un număr limitat de stări O stare este păstrată pacircnă icircn

momentul apariţiei unui eveniment moment icircn care se poate trece icircn altă stare şisau efectua o

acţiune

Aceste stări posibile sunt (denumirile sunt asemănătoare cu cele utilizate de netstat) cele din

tabelul 71

Tabela Stările diagramei de stări TCP

Stare Descriere

CLOSED Nu există conexiune

LISTEN Serverul aşteaptă cereri de la clienţi

SYN_SENT Cerere de iniţiere (activă) a conexiunii Se

aşteaptă confirmarea

SYN_RCVD S-a primit o cerere de iniţiere conexiune

ESTABLISHED S-a stabilit conexiunea

FIN_WAIT_1 Aplicaţia a solicitat icircnchiderea conexiunii

FIN_WAIT_2 Serverul a acceptat icircnchiderea conexiunii

CLOSING Ambele părţi solicită simultan icircnchiderea

conexiunii

TIME_WAIT Conexiune icircnchisă dar se aşteaptă ca

pachetele retransmise să dispară

CLOSE_WAIT Serverul aşteaptă icircnchiderea dinspre partea

aplicaţiei

LAST_ACK Serverul a icircnchis conexiunea Aşteaptă

ultima confirmare

Icircn diagrama ilustrată icircn figura 74 putem observa 3 tipuri de tranziţii icircntre cele 11 stări tranziţii

ce corespund unei funcţionări normale pentru client (linii normale continue) pentru server (linii

normale icircntrerupte) şi tranziţii pentru situaţii nestandard (linii subţiri continue)

O comportarea normală pentru client presupune parcurgerea următoarelor stări CLOSED

SYN_SEND ESTABLISHED FIN_WAY_1 FIN_WAY_2 TIME_WAIT

Iniţial clientul TCP se află icircn starea CLOSED

Aşteptacircnd icircn starea CLOSED clientul poate primi de la aplicaţie o cerere de iniţiere

activă a unei conexiuni Trimite un segment SYN şi trece icircn starea SYN_SENT

Icircn starea SYN_SENT clientul aşteaptă de la server un segment ACK+SYN după care

trimite un ACK şi trece icircn starea ESTABLISHED Din acest moment poate icircncepe

transferul efectiv de date Clientul va rămacircne icircn această stare cacirct timp are de trimisprimit

date

Aflat icircn această stare clientul TCP poate primi din partea aplicaţiei o cerere de icircnchidere a

conexiunii Icircn acest caz va trimit un segment FIN şi trece icircn starea FIN_WAIT_1

Icircn această stare clientul aşteaptă ACK din partea serverului După ce-l primeşte

conexiunea icircntr-un sens se va icircnchide şi clientul trece icircn starea FIN_WAIT_2

Starea FIN_WAIT_2 durează pacircnă cacircnd primeşte cererea de icircnchidere a conexiunii FIN

din partea serverului Trimite ACK şi va trece icircn starea TIME_WAIT

Icircn această stare se va porni un timer cu valoarea setată la dublul timpului de viaţă estimat

pentru un segment de lungime maximă MSL (Maximum Segment Lifetime) Acest timer

permite retransmiterea ACK-ului icircn cazul icircn care acesta se pierde (celălalt capăt va da

timeout şi va retransmite segmentul FIN) Icircn tot acest time cei doi sockeţi (de la client şi

server) nu vor putea fi reutilizaţi Totodată pachetele icircntacircrziate care sosesc icircn această

perioadă sunt ignorate După expirarea acestui timer clientul revine icircn starea iniţială

CLOSED

Din punctul de vedere al unui server o comportare standard parcurge următoarele stări

CLOSED LISTEN SYN_RCVD ESTABLISHED CLOSE_WAIT şi LAST_ACK

Iniţial serverul TCP se află icircn starea CLOSED

Icircn această stare poate primi de la aplicaţia server o cerere de iniţiere activă şi trece icircn

starea LISTEN

Aflat icircn starea LISTEN serverului TCP poate recepţiona un segment SYN de la un client

TCP Icircn acest caz va trimite ACK+SYN şi va trece icircn starea SYN_RCVD

Icircn această stare serverul aşteaptă primirea confirmării de la client moment icircn care

conexiunea e stabilită icircn ambele sensuri şi se poate icircncepe transferul de date (starea

ESTABLISHED)

Clientul TCP poate solicita icircnchiderea conexiunii trimiţacircnd un segment FIN către server

Icircn acest caz serverul TCP trimite confirmarea şi trece icircn starea CLOSE_WAIT

Icircn această stare serverul aşteaptă să primească din partea programului server icircnchiderea

conexiunii moment icircn care va trimite către client un segment FIN şi trece icircn starea

LAST_ACK

Serverul aşteaptă primirea ultimei confirmări de la client după care revine icircn starea

CLOSED

Atacirct serverul cacirct şi clientul TCP se pot afla icircn oricare din cele 11 stări ale diagramei

Figura Diagrama de stări pentru TCP

4 Controlul fluxului

Dacă icircncă de la icircnceput s-a reuşit stabilirea formatului unui pachet TCP şi a modulului icircn care

trebuie să se facă icircnchiderea şi deschiderea unei conexiuni nu acelaşi lucru se poate spune şi

despre modul icircn care ar trebui să se realizeze controlul fluxului Ţinacircnd seama icircnsă că din 1989

(de cacircnd datează RFC-ul 2581 cel despre care am menţionat că specifică icircn mod clar modul icircn

care trebuie să se comporte o implementare de TCP) TCP-ul a rămas neschimbat putem să icircl

considerăm un rezultat important al domeniului reţelor de calculatoare

Icircn cele ce urmează vom icircnţelege prin controlul fluxului totalitatea algoritmilor care permit

atingerea unei viteze de transfer punct-la-punct cacirct mai mare pentru toate conexiunile existente

Icircn principal aceşti algoritmi stabilesc modul icircn care segmentele şi confirmările trebuie trimise şi

ce acţiuni trebuie executate icircn situaţiile icircn care răspunsurile aşteptate de la celălalt capăt icircntacircrzie

să vină

Subsections

Icircntacircrzierea confirmărilor

Algoritmul Nagle

Fereastra glisantă

Slow start

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Evitarea congestiei

Fast Retransmission Fast Recovery

Sindromul ``Silly Window

TCP Keepalive Timer

Icircntacircrzierea confirmărilor

O modalitate simplă de generare a confirmărilor este de a trimite cacircte una pentru fiecare segment

primit Această politică prezintă avantajul de a face comunicaţia self-clocking icircnsă este

ineficientă dacă segmentele care nu conţin decacirct confirmări sunt urmate la scurtă distanţă (cacircteva

zeci de milisecunde) de segmente ce conţin date efective Pentru a evita această situaţie se

procedează2 la icircntacircrzierea (200ms este o valoare uzuală icircn RFC 1122 se specifică o valoare

maximă de 500ms) a segmentelor care conţin doar confirmări Această strategie face posibil ca

un răspuns generat de primirea unor date să plece sper celălalt capăt icircn acelaşi segment cu

confirmarea

Observaţie deoarece este dificil de menţinut timere pentru fiecare confirmare diferenţa de

200ms este calculată de un timer global Din acest motiv modul efectiv de comportare poate fi

descris şi icircn felul următor cacircnd un segment nu conţine decacirct o confirmare el este pus icircntr-o

coadă ce va fi inspectată de un proces care din 200 icircn 200 ms trimite tot ce s-a acumulat icircn

coada

Footnotes

2

Acest comportament a fost propus de David D Clark icircn iulie 1982 icircn RFC 813

Algoritmul Nagle

Acest algoritm3 icircncearcă să icircmbunătăţească performanţele exploatacircnd următoarea caracteristică

foarte des icircntacirclnită icircn dialogul dintre două staţii dacă se icircncearcă trimiterea unor date de

dimensiune mică icircnsă există icircncă date neconfirmate de partener atunci ele sunt buffer-ate şi

trimise icircntr-un segment mai mare cacircnd soseşte confirmarea aşteptată Icircn acest fel se poate evita

generarea datagramelor mici (tinygrame) icircn situaţia unei legături lente Icircn cazul unei legături

rapide confirmările vor veni repede şi icircntacircrzierea introdusă de algoritm va neglijabilă

Există icircnsă şi cazuri icircn care acest algoritm duce la deprecierea performanţelor mesajele scurte

generate de mişcările mouse-ului icircn cazul folosirii unui server X Window sau utilizarea tastelor

care trimit mai mult de un caracter (secvenţe escape) Pentru a rezolva aceste inconveninte API-

ul de utilizare a TCP-ului trebuie să ofere o modalitate de a dezactiva acest algoritm (icircn sistemele

bazate pe sockeţi există icircn acest scop opţiunea TCP_NODELAY)

Footnotes

algoritm3

Algoritmul aparţinacircnd lui John Nagle a fost propus icircn ianuarie 1984 icircn RFC 896

Fereastra glisantă

Algoritmul implementat de TCP pentru a implementa transferul sigur de date este cunoscut icircn

teorie sub numele de Go-Back-N Icircn acest algoritm se utilizează numere de secvenţă pentru a

distinge pachetele icircntre ele şi o coadă (dimensiunea maximă a cozii reprezintă fereastra) de

pachetele a căror confirmare se aşteaptă Pachetele se icircmpart icircn 4 categorii

1 pachete trimis şi pentru care s-a primit confirmare

2 pachete trimise şi pentru care se aşteaptă icircncă confirmarea

3 pachete care nu au fost trimise icircncă dar care nu depăşesc limitele ferestrei şi deci pot fi

trimise

4 pachete care icircncă nu au fost trimite şi care nici nu vor putea fi trimise decacirct după ce au

fost trimise toate pachetele din categoria 3 şi s-au primit o parte din confirmările la

pachetele din categoria 2

Dacă confirmările pentru pachetele din categoria 2 icircntacircrzie prea mult (un mecanism de timer-e

informează asupra acestui lucru) atunci ele vor fi retrimise Icircn versiunea iniţială TCP-ul nu

permitea decacirct confirmări pozitive ceea ce icircnseamnă că avansarea ferestrei se va icircmpotmoli la

segmentele neconfirmate Cum se poate evita aceasta situaţie vom discuta icircn detaliu icircn capitolele

următoare O soluţie foarte radicală o constituie introducerea de confirmări selective (acest lucru

este realizat de RFC 2018 din octombrie 1996) Această modifică face ca TCP-ul actual să fie un

hibrid de Go-Back-N şi Selective Repeat

Deoarece dimensiunea ferestrei este anunţată la fiecare segment un client lent poate ca pe măsură

ce trimite confirmările să informeze despre progresul icircnregistrat la livrarea datelor următorului

nivel (aplicaţie) Dacă datele vin prea repede pentru viteza cu care clientul procesează datele

fereastra fereastra se va dimiua şi chiar icircnchide (acest lucru se realizează anunţacircnd o fereastră de

dimensiune zero) Cum se realizează efectiv redeschiderea vom analiza icircntr-un capitol viitor

Slow start

Un transfer de date TCP poate să icircnceapă prin transmiterea de segmente pacircnă la umplerea

icircntregii ferestre după care fie se primesc confirmări care vor permite unor noi pachete să fie

trimise fie vor expira timer-ele de retransmisie şi se va icircncepe retrimiterea pachetelor de la

icircnceputul ferestrei Din păcate un astfel de comportament poate duce la pomparea icircn reţea a unui

număr de pachete prea mare pentru capacitatea disponibilă efectiv icircnrăutăţind congestia Pentru

a evita acest lucru s-a propus următoarea soluţie4 iniţial se trimite un segment după primirea

confirmării lui se trimit două segmente după sosirea confirmărilor pentru ele se trimit patru

segmente şi aşa mai departe La un moment dat fie vor icircncepe să se piardă segmente (un indiciu

că s-a atins capacitatea maximă a canalului) fie se va umple fereastra pe care o anunţă cel care

primeşte Trebuie să remarcam că datorită creşterii exponenţiale a numărului de segmente se va

atinge destul de repede una din cele două situaţii

Modalitatea efectivă de implementare a acestui algoritm are la bază utilizarea unei ferestre de

congestie (congestion window cwnd) care este iniţializată cu dimensiunea unui segment (cwnd

se calculează icircn octeţi) şi la fiecare pas este dublată fereastra efectivă din cadrul căreia se pot

trimite segmente este dată de minimul dintre ultima fereastra comunicată de partener şi cwnd

Footnotes

soluţie4

Soluţia aparţine lui V Jacobson şi a fost prezentată icircn 1988 la conferinţă ACM

SIGCOMM-88

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Deoarece TCP trebuie să funcţioneze icircn condiţii variate de latenţă modul icircn care se face

retransmiterea trebuie să fie cacirct mai flexibil (şi simplu icircn acelaşi timp pentru a introduce un

overhead cacirct mai mic) Timpul cacirct se aşteaptă venirea unei confirmări (retransmission timeout

RTO) este calculat prin cronometrarea timpului care icirci ia unui segment trimis să fie confirmat

Pentru o anumită conexiune se cronometrează cacircte un singur segment la un moment dat iar pe

baza RTT-ului măsurat se actualizează valoare RTO-ului

Icircn RFC 793 formula de calcul a RTO-ului este următoarea

unde este ultimul RTT măsurat este o estimare ponderată pentru RTT este un coeficient

de ponderare care icircn general are valoarea iar este un coeficient cu o valoare recomandată

de După cum se poate observa icircn valoarea lui este inclusă icircn mare măsură vechea valoarea

Icircn acest fel ajustarea RTT-ului se face treptat Din păcate acest mod de calcul nu funcţionează

bine la variaţii mari ale RTT-ului ducacircnd la creşterea numărului de retransmisii exact atunci

cacircnd fenomenul de congestie icircncepe să apară

Pentru a remedia aceste neajunsuri V Jacobsen a propus icircn 1988 o nouă metodă de calcul o

metodă care ţine seama seamă şi de modul icircn care variază diferenţa dintre RTT-uri Formulele

folosite sunt următoarele

unde este un estimare pentru media RTT-urilor este o estimare pentru abaterea RTT-urilor

faţă de medie (o aproximaţie suficientă pentru abaterea pătratică medie care icircnsă este mult mai

costisitor de calculat) este diferenţa dintre RTT-ul măsurat ( ) şi estimarea curentă ( )

Coeficientul cu care este actualizată estimarea curentă are valoarea de iar cel cu care este

actualizat estimarea abaterii este La stabilirea unei conexiuni valorile pentru şi sunt

alese astfel icircncacirct să rezulte un RTT de secunde şi un de 3 secunde (aceste recomandări

sunt făcute de RFC 1122)

Dacă pentru un anumit segment nu se primeşte confirmarea icircn intervalul indicat de el va fi

retrimis şi noul este dublat Valoarea maximă admisă pentru este de 240 secunde

Deoarece icircn cazul retrimiterilor nu se poate determina cu exactitate căruia din segmentele trimise

aparţine confirmarea actualizarea estimărilor este amacircnată pacircnă cacircnd se reuşeşte trimiterea

corectă (s-a primit confirmare) fără retransmitere(``din prima) a unui segment Acest artificiu

(deloc neimportant) care permite evitarea actualizarea eronată a estimărilor este cunoscut sub

numele de algoritmul lui Karn şi a fost propus icircn 1987 de P Karn şi C Partridge

Evitarea congestiei

Dacă cei doi parteneri care comunică prelucrează datele suficient de repede şi vor să transfere un

volum mare de date atunci limitarea de care se vor lovi este cea dată de viteza reţelei Din cauza

modului ``best-effort pe care IP-ul icircl oferă cacircnd canalul de comunicaţie este saturat o parte din

segmentele TCP se vor pierde Icircn mod poate paradoxal atacirct transmiţătorului cacirct şi receptorul se

pot afla icircn poziţia de a fi primii icircn detectarea pierderii unui segment Unul din indiciile de la

transmiţător care semnalează pierderea unui segment este (icircn mod evident) apariţia 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 icircn varianta iniţială nu

permite decacirct confirmări pozitive singurul lucru pe care receptorul icircl poate face este ca la fiecare

segment out-of-order primit să trimită o confirmare indicacircnd prin aceasta că la el continuă să

vină segmente icircnsă cel indicat de numărul de secvenţă de confirmare lipseşte Primirea acestor

confirmări multiple este al doilea mod icircn care transmiţătorul poate afla de apariţia congestiei

Algoritmul ce trebuie aplicat icircn momentul icircn care se detectează apariţia congestiei este cunoscut

sub numele de ``evitarea congestiei (congestion avoidence) Principiul care stă la baza lui este

ca la apariţia congestiei fie să se treacă la o incrementare liniară a dimensiunii ferestrei dacă

congestia a fost detectată ca urmare a primirii unor confirmări identice repetate fie să se reia

slow start-ul icircn cazul icircn care congestia s-a detectat prin expirarea unui timer de timeout

Implementarea acestui algoritm se bazează pe utilizarea unui nou contor (sstresh) care să indice

dimensiunea ferestrei de la care se trece de la incrementarea exponenţială la cea liniară

Algoritmul efectiv este următorul

1 la stabilirea unei noi conexiuni se pleacă cu sstresh iniţializat la valoare de 64K şi cwnd

la dimensiunea unui segment

2 trimiterea de segmente se face fără a depăşi minimul dintre fereastra publicată de partener

(pentru a nu depăşi capacitatea de procesesare a partenerului) şi cwnd-ul curent (pentru a

nu depăşi limita impusă de capacitatea reţelei)

3 la apariţia congestiei sstresh este setat la jumătatea valorii ferestrei curente (minimul

dintre fereastra anunţată de partener şi cwnd icircnsă cel puţin dimensiunea corespunzătoare

pentru două segmente) dacă congestia a fost detectată prin expirarea unui timer de

timeout atunci cwnd este iniţializat cu dimensiunea unui segment

4 la primirea unei confirmări incrementarea se face icircn două moduri icircn funcţie de relaţie icircn

care se află cwnd şi sstresh

1 dacă cwnd e mai mic sau egal cu sstresh se face incrementarea exponenţială

caracteristică slow start-ului (care de fapt nu e deloc slow icircn cazul de faţă)

2 dacă cwnd e mai mare ca sstresh atunci se face o incrementare cu dimensiunea

unui segment

Fast Retransmission Fast Recovery

După cum am văzut un receptor care primeşte segmente out-of-order va trimite transmiţătorului

confirmări duplicate Algoritmul denumit ``fast retransmission recomandă următoarele două

comportamenet

1 un receptor care detectează segmente out-of order trebuie să nu icircntacircrzie trimiterea de

confirmări (după cum am văzut icircn general confimările sunt icircntacircrziate micşora numărul de

pachete fără date care sunt transferate)

2 un transmiţător care care primeşte mai mult de trei confirmări duplicate trebuie să

retrimită segmentul indicat ca fiind neprimit de confirmările icircn cauză fără a aştepta

expirarea timer-ul de timeout

Algoritmul de ``fast recovery icircncearcă să optimizeze şi mai mult comportamentul

transmiţătorului care detectează un număr de trei sau mai multe confimări duplicate Mai exact el

recomandă trecerea la actualizarea liniară a ferestrei (congestion avoidance) Acest tip de

comportament se poate justifica prin următorul raţionament deoarece icircncă mai sunt transferate

date icircntre cei doi parteneri (şi acest lucru se icircntacircmplă sigur de vreme ce sosesc confirmări

duplicate icircn cazul acesta) icircnseamnă că transferul nu este afectat de o congestie severă şi prin

urmare trecerea la slow start nu e (icircncă) necesară (slow start-ul eliberează aproape complet

canalul deoarece cwnd este resetat la dimensiunea unui singur segment)

Cei doi algoritmi pot fi implementaţi icircn felul următor

1 cacircnd se detectează trei confirmări consecutive identice se setează sstresh la jumătate din

valoarea cwnd se retransmite segmentul care s-a pierdut şi se setează cwnd la valoarea

egală cu sstresh plus dimensiunea a trei segmente (acest lucru va face ca algoritmul de

incrementare a cwnd să treacă la incrementare liniară)

2 la fiecare confirmare duplicată care mai soseşte se incrementează cwnd se incrementează

cu dimensiunea unui segment

3 cacircnd icircncetează primirea de confirmări duplicate (segmentul retrimis a ajuns cu bine la

receptor şi s-a trimis o confirmare care acoperă segmentul care se pierduse iniţial) cwnd

este setat la valoarea sstresh

Sindromul ``Silly Window

Protocoalele bazate pe fereastră glisantă (cum este şi TCP-ul) pot să ajungă icircn situaţia deloc

fericită de trimite un număr mare de segmente mici icircn loc de segmente de dimensiune maximă

Acest tip de comportament este cunoscut sub numele de sindromul ``silly window

O modalitate prin care TCP-ul poate să cadă victimă acestui tip de comportament este

deschiderea de ferestre cu dimensiune foarte mică O altă situaţia nefericită este cea icircn care un

transmiţător este ``lacom şi trimite date indiferent de cacirct de mică este fereastra (după cum vom

vedea imediat uneori are sens şi un astfel de comportament) Algoritmul de evitare a acestor

neajunsuri este următorul

1 un receptor nu trebuie să anunţe deschideri de ferestre mici Mai exact nu se recomandă

anunţarea unei incrementări a ferestrei mai mică decacirct dimensiunea unui segment (MSS)

sau jumătate din buffer-ul aflat la dispoziţia receptorului oricare din ele e mai mică

2 un transmiţător va trimite date doar icircn următoarele cazuri

1 se poate trimite un segment icircntreg

2 se poate trimite jumătate din dimensiunea celei mai mari ferestre pe care

partenerul a publicat-o pacircnă acum

3 toate datele trimise pacircnă acum au fost confirmate sau algoritmul Nagle este

dezactivat şi se trimit toate datele care sunt icircn buffer-ul de trimitere

Cacircteva justificări cazul 2b tratează cazul icircn care partenerul anunţă ferestre mai mici decacirct

dimensiunea unui segment iar cazul 2c impune condiţiile respectării algoritmului Nagle după

cum se vede dacă algoritmul Nagle este activ şi s-au acumulat destul date mai exact cacirct

dimensiunea unui segment el va fi trimis chiar dacă există segmente neconfirmate Pentru

implementarea comportamentului impus de 2b un transmiţător trebuie să ţină evidenţa celei mai

mari ferestre pe care partenerul a anunţat-o Ţinacircnd seama că dimensiunea acestor buffer-e nu se

modifică acest mod de a icircncerca determinarea lor este suficient

O altă problemă legată tot de ferestre este cazul icircnchiderii acesteia Un mod icircn care s-ar putea

anunţa redeschiderea este trimiterea de către receptor a unei confirmări (duplicat) care să anunţe

redeschiderea la o anumită valoare a ferestrei Deoarece acest pachet nu trebuie confirmat icircn mod

special şi s-ar putea să se piardă se poate ajunge icircn situaţia icircn care receptorul a anunţat

redeschiderea ferestrei segmentul s-a pierdut iar transmiţătorul icircncă mai icircl mai aşteaptă pentru a

putea continua transferul Rezolvarea la această problemă s-a făcut prin impunerea unui alt

comportament

1 transmiţătorul va trimite segmente cu dimensiunea datelor de un octet prin care sondează

deschiderea ferestrei intervalul la care se sondează redeschiderea ferestrei se dublează

(exponenţial backoff) icircn RFC 793 dimensiunea maximă recomandată este de 2 minute

icircnsă icircn RFC 1122 se specifică că maximul este acelaşi cu cel din cazul retransmisiei (240

secunde)

2 receptorul trebuie să refuze aceste pachete răspunzacircnd cu segmente de confirmare care

indică neprimirea octetului respectiv

Observaţie timer-ul special necesar pentru implementare la transmiţător a comportamentului de mai sus este cunoscut sub numele de ``TCP Persistent Timer Numele este justificat de faptul că sondarea deschiderii se va face pacircnă cacircnd fie fereastra se deschide fie conexiunea se icircntrerupe TCP Keepalive Timer

Un lucru interesant despre TCP este faptul că dacă nivelele superioare nu comunică nimic icircntre

ele pentru o perioadă lungă 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 icircn care au trecut cu succes de faza stabilirii legăturii Dacă nivelurile

inferioare (reţeaIP fizic) devin temporar indisponibile cacirct tip cei doi nu vor să comunice atunci

acest lucru nu va perturba icircn nici un fel activitatea şi acest lucru este acceptabil Problemele

icircncep să apară icircn momentul icircn care cei doi doresc să comunice şi nivelele inferioare nu mai

permit acest lucru Evident că cel care va dori să comunice ceva va detecta icircntreruperea legăturii

şi va icircnchide conexiunea Ce se icircntacircmplă icircnsă dacă celălalt capăt nu are nimic de comunicat (de

exemplu este un server care oferă anumite servicii) Pentru el legătura va fi icircn continuare activă

şi icircn general anumite resurse vor fi rezervate pentru aceasta Rezolvarea acestei situaţii este dată

de introducerea unei mecanism de sondare a stării legăturii pe baza unui timer (TCP Keepalive

Timer) care se declanşează din două icircn două ore La fiecare expirare a timer-ului se trimite un

segment fără date care confirmă datele primite pacircnă atunci Răspunsul care trebuie primit este tot

un segment fără date care confirmă datele primite de partener (practic o re-publicare a stării celor

doi parteneri) Dacă răspunsul nu este primit timp de 75 secunde atunci segmentul va fi retrimis

Dacă după 10 astfel de icircncercări tot nu s-a primit nici un răspuns atunci conexiunea se va

considera terminată şi se va anunţa nivelul superior asupra acestui lucru

Observaţii

dacă o staţie primeşte segmente de keepalive despre conexiuni care nu mai sunt active

(de exemplu a fost resetat) atunci va răspunde cu segmente de reset (acesta e un procedeu

standard)

RFC 1122 specifică că facilitatea de keepalive trebuie activată icircn mod explicit

3 Studii de caz

Subsections

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

1 Fragmentarea pachetelor UDP

Deoarece UDP-ul este un serviciu fără conexiune toate datele pe care le primeşte de la nivelul

superior sunt icircncapsulate icircntr-o singură datagramă UDP care apoi va forma un pachet IP Dacă

pachetul IP astfel obţinut este prea mare atunci mecanismele IP de fragmentare icircl vor sparge icircn

bucăţi Exemplul următor icircncearcă să studieze exact acest fenomen

Pe maşina athos rulează un server de UDP pe portul 50007 Pe o altă maşină frodo aflată icircn

reţeaua locală este rulat un client care poate fi configurat să trimită un pachet UDP de o anumită

lungime Pentru a putea observa ce se icircntacircmplă pe athos este rulat tcpdump

Deoarece MTU-ul pentru o reţea Ethernet este icircn general 1500 şi antetul IP plus cel UDP ocupă

20 + 8 = 28 octeţi o datagramă UDP de dimensiune 1472 ar trebui sa fie trimisă nefragmentată

Pentru siguranţă folosind clientul de pe athos s-a trimis mai icircntacirci o datagramă UDP cu 1471

octeţi de date şi apoi icircncă una cu 1472 Pentru ambele tcpdump a indicat trimiterea lor fără

fragmentare

182556721144 frodonoi33274 gt athosnoi50007 udp 1471 (DF) (ttl 64 id

51481 len 1499)

182559846764 frodonoi33274 gt athosnoi50007 udp 1472 (DF) (ttl 64 id

51793 len 1500)

La o dimensiune de 1473 ar trebui ca trimiterea să genereze două pachete IP unul care să

conţină primii antetul UDP plus primii 1472 octeţi de date şi icircncă un pachet IP care conţine un

singur octet Iată ce indică tcpdump-ul

182605705813 frodonoi gt athosnoi udp (frag 3627411480) (ttl 64 len

21)

182605706116 frodonoi33274 gt athosnoi50007 udp 1473 (frag

3627414800+) (ttl 64 len 1500)

Intr-adevăr au fost generate două pachete IP

primul conţine doar un singur octet de date şi reprezintă ultimul fragment (bitul de more

fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest

lucru) care a fost spartă icircn bucăţi deplasamentul octetului primit in datagrama originală

este 1480

al doilea pachet este primul fragment din datagrama UDP şi conţine antetul UDP (din

cauza asta datele efective ocupă doar 1480 octeţi) deplasamentul este 0 şi bitul de more

fragments este setat (acest lucru este indicat de semnul ``+ de după deplasament)

După cum se poate observa ambele pachete poartă acelaşi număr de identificare (36274) Acest

lucru icircmpreună cu informaţiile date de flag-ul more fragments permite reconstrucţia la

destinaţie a datagramei UDP originale O problemă a acestui mod de fragmentare e că icircn cazul

pierderii unui fragment icircntreaga datagramă va fi compromisă şi va trebui retrimisă icircn icircntregime

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 11: udp tcp

dimensiunea ferestrei şi opţional poate seta factorul de scalare şi dimensiunea maximă a

segmentului acceptat

3 Clientul trimite un segment cu confirmarea cererii din partea serverului (ACK setat +

completează numărul confirmat cu numărul de secvenţa primit + 1) Ca şi icircn cazul

pasului 2 trebuie să seteze dimensiunea ferestrei Acest pachet poate conţine date

Subsections

1 Deschiderea simultană

1 Deschiderea simultană

Se poate icircntacircmpla ca uneori cele două capete care vor să comunice să icircncerce să stabilească

conexiunea simultan Icircn acest caz după ce fiecare a trimis segmentul de iniţiere (iniţiere activă)

ambele vor trimite un segment cu SYN + ACK şi se va stabili o singură conexiune nu două

Protocolul de terminare

Oricare dintre cele două părţi poate solicita icircnchiderea conexiunii dar conexiunea fiind full-

duplex transferul de date icircn celălalt sens poate continua (această situaţie e denumită half-close)

O icircnchidere completă a unei conexiuni TCP presupune următorii paşi

1 Clientul trimite un segment cu flag-ul FIN activat solicitacircnd icircnchiderea conexiunii

2 Serverul trimite un segment ACK confirmacircnd primirea cererea Numărul de confirmare

se completează normal ca numărul de secvenţă primit + 1

3 Serverul continuă să trimită date către client şi cacircnd doreşte să icircnchidă şi el conexiunea

trimite un segment cu FIN activat

4 Clientul trimite un pachet ACK confirmacircnd icircnchiderea conexiunii

Cel care iniţiază primul procedura de icircnchidere (trimite primul FIN) realizează o icircnchidere activă

(active close) iar celălalt capăt o icircnchidere pasivă (passive close) Icircn mod normal cel care

realizează iniţierea activă va fi primul ce va trimite FIN dar oricare dintre cei doi poate icircnchide

activ conexiunea

Subsections

2 Terminarea simultană

3 Resetarea conexiunii

2 Terminarea simultană

Icircn mod similar cu deschiderea simultană există posibilitatea ca ambele capete ale conexiunii TCP

să iniţieze simultan procedura de icircnchidere a conexiunii Icircn acest caz ambele părţi vor trimite

FIN şi vor aştepta primirea unui ACK Icircn continuare fiecare va primi cererea de terminare şi va

trimite ACK Se observă că numărul de segmente transferate pentru realizarea icircnchiderii

conexiunii (4 segmente) este acelaşi ca la terminarea normală

3 Resetarea conexiunii

Există situaţii icircn care TCP doreşte resetarea conexiunii De exemplu dacă se solicită iniţierea

unei conexiuni la un port inexistent Icircn acest caz cealaltă parte va trimite un segment cu bitul

RST setat pentru a anula solicitarea O altă situaţie este atunci cacircnd se constată că celalalt capăt

al conexiunii nu răspunde un anumit timp (timeout)

Diagrama de stări

Toate evenimentele ce au loc icircn timpul stabilirii conexiunii transferului şi icircnchiderii conexiunii

pot fi rezumate printr-un automat finit cunoscut sub numele de diagrama de stări După cum

chiar numele sugerează este o maşină cu un număr limitat de stări O stare este păstrată pacircnă icircn

momentul apariţiei unui eveniment moment icircn care se poate trece icircn altă stare şisau efectua o

acţiune

Aceste stări posibile sunt (denumirile sunt asemănătoare cu cele utilizate de netstat) cele din

tabelul 71

Tabela Stările diagramei de stări TCP

Stare Descriere

CLOSED Nu există conexiune

LISTEN Serverul aşteaptă cereri de la clienţi

SYN_SENT Cerere de iniţiere (activă) a conexiunii Se

aşteaptă confirmarea

SYN_RCVD S-a primit o cerere de iniţiere conexiune

ESTABLISHED S-a stabilit conexiunea

FIN_WAIT_1 Aplicaţia a solicitat icircnchiderea conexiunii

FIN_WAIT_2 Serverul a acceptat icircnchiderea conexiunii

CLOSING Ambele părţi solicită simultan icircnchiderea

conexiunii

TIME_WAIT Conexiune icircnchisă dar se aşteaptă ca

pachetele retransmise să dispară

CLOSE_WAIT Serverul aşteaptă icircnchiderea dinspre partea

aplicaţiei

LAST_ACK Serverul a icircnchis conexiunea Aşteaptă

ultima confirmare

Icircn diagrama ilustrată icircn figura 74 putem observa 3 tipuri de tranziţii icircntre cele 11 stări tranziţii

ce corespund unei funcţionări normale pentru client (linii normale continue) pentru server (linii

normale icircntrerupte) şi tranziţii pentru situaţii nestandard (linii subţiri continue)

O comportarea normală pentru client presupune parcurgerea următoarelor stări CLOSED

SYN_SEND ESTABLISHED FIN_WAY_1 FIN_WAY_2 TIME_WAIT

Iniţial clientul TCP se află icircn starea CLOSED

Aşteptacircnd icircn starea CLOSED clientul poate primi de la aplicaţie o cerere de iniţiere

activă a unei conexiuni Trimite un segment SYN şi trece icircn starea SYN_SENT

Icircn starea SYN_SENT clientul aşteaptă de la server un segment ACK+SYN după care

trimite un ACK şi trece icircn starea ESTABLISHED Din acest moment poate icircncepe

transferul efectiv de date Clientul va rămacircne icircn această stare cacirct timp are de trimisprimit

date

Aflat icircn această stare clientul TCP poate primi din partea aplicaţiei o cerere de icircnchidere a

conexiunii Icircn acest caz va trimit un segment FIN şi trece icircn starea FIN_WAIT_1

Icircn această stare clientul aşteaptă ACK din partea serverului După ce-l primeşte

conexiunea icircntr-un sens se va icircnchide şi clientul trece icircn starea FIN_WAIT_2

Starea FIN_WAIT_2 durează pacircnă cacircnd primeşte cererea de icircnchidere a conexiunii FIN

din partea serverului Trimite ACK şi va trece icircn starea TIME_WAIT

Icircn această stare se va porni un timer cu valoarea setată la dublul timpului de viaţă estimat

pentru un segment de lungime maximă MSL (Maximum Segment Lifetime) Acest timer

permite retransmiterea ACK-ului icircn cazul icircn care acesta se pierde (celălalt capăt va da

timeout şi va retransmite segmentul FIN) Icircn tot acest time cei doi sockeţi (de la client şi

server) nu vor putea fi reutilizaţi Totodată pachetele icircntacircrziate care sosesc icircn această

perioadă sunt ignorate După expirarea acestui timer clientul revine icircn starea iniţială

CLOSED

Din punctul de vedere al unui server o comportare standard parcurge următoarele stări

CLOSED LISTEN SYN_RCVD ESTABLISHED CLOSE_WAIT şi LAST_ACK

Iniţial serverul TCP se află icircn starea CLOSED

Icircn această stare poate primi de la aplicaţia server o cerere de iniţiere activă şi trece icircn

starea LISTEN

Aflat icircn starea LISTEN serverului TCP poate recepţiona un segment SYN de la un client

TCP Icircn acest caz va trimite ACK+SYN şi va trece icircn starea SYN_RCVD

Icircn această stare serverul aşteaptă primirea confirmării de la client moment icircn care

conexiunea e stabilită icircn ambele sensuri şi se poate icircncepe transferul de date (starea

ESTABLISHED)

Clientul TCP poate solicita icircnchiderea conexiunii trimiţacircnd un segment FIN către server

Icircn acest caz serverul TCP trimite confirmarea şi trece icircn starea CLOSE_WAIT

Icircn această stare serverul aşteaptă să primească din partea programului server icircnchiderea

conexiunii moment icircn care va trimite către client un segment FIN şi trece icircn starea

LAST_ACK

Serverul aşteaptă primirea ultimei confirmări de la client după care revine icircn starea

CLOSED

Atacirct serverul cacirct şi clientul TCP se pot afla icircn oricare din cele 11 stări ale diagramei

Figura Diagrama de stări pentru TCP

4 Controlul fluxului

Dacă icircncă de la icircnceput s-a reuşit stabilirea formatului unui pachet TCP şi a modulului icircn care

trebuie să se facă icircnchiderea şi deschiderea unei conexiuni nu acelaşi lucru se poate spune şi

despre modul icircn care ar trebui să se realizeze controlul fluxului Ţinacircnd seama icircnsă că din 1989

(de cacircnd datează RFC-ul 2581 cel despre care am menţionat că specifică icircn mod clar modul icircn

care trebuie să se comporte o implementare de TCP) TCP-ul a rămas neschimbat putem să icircl

considerăm un rezultat important al domeniului reţelor de calculatoare

Icircn cele ce urmează vom icircnţelege prin controlul fluxului totalitatea algoritmilor care permit

atingerea unei viteze de transfer punct-la-punct cacirct mai mare pentru toate conexiunile existente

Icircn principal aceşti algoritmi stabilesc modul icircn care segmentele şi confirmările trebuie trimise şi

ce acţiuni trebuie executate icircn situaţiile icircn care răspunsurile aşteptate de la celălalt capăt icircntacircrzie

să vină

Subsections

Icircntacircrzierea confirmărilor

Algoritmul Nagle

Fereastra glisantă

Slow start

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Evitarea congestiei

Fast Retransmission Fast Recovery

Sindromul ``Silly Window

TCP Keepalive Timer

Icircntacircrzierea confirmărilor

O modalitate simplă de generare a confirmărilor este de a trimite cacircte una pentru fiecare segment

primit Această politică prezintă avantajul de a face comunicaţia self-clocking icircnsă este

ineficientă dacă segmentele care nu conţin decacirct confirmări sunt urmate la scurtă distanţă (cacircteva

zeci de milisecunde) de segmente ce conţin date efective Pentru a evita această situaţie se

procedează2 la icircntacircrzierea (200ms este o valoare uzuală icircn RFC 1122 se specifică o valoare

maximă de 500ms) a segmentelor care conţin doar confirmări Această strategie face posibil ca

un răspuns generat de primirea unor date să plece sper celălalt capăt icircn acelaşi segment cu

confirmarea

Observaţie deoarece este dificil de menţinut timere pentru fiecare confirmare diferenţa de

200ms este calculată de un timer global Din acest motiv modul efectiv de comportare poate fi

descris şi icircn felul următor cacircnd un segment nu conţine decacirct o confirmare el este pus icircntr-o

coadă ce va fi inspectată de un proces care din 200 icircn 200 ms trimite tot ce s-a acumulat icircn

coada

Footnotes

2

Acest comportament a fost propus de David D Clark icircn iulie 1982 icircn RFC 813

Algoritmul Nagle

Acest algoritm3 icircncearcă să icircmbunătăţească performanţele exploatacircnd următoarea caracteristică

foarte des icircntacirclnită icircn dialogul dintre două staţii dacă se icircncearcă trimiterea unor date de

dimensiune mică icircnsă există icircncă date neconfirmate de partener atunci ele sunt buffer-ate şi

trimise icircntr-un segment mai mare cacircnd soseşte confirmarea aşteptată Icircn acest fel se poate evita

generarea datagramelor mici (tinygrame) icircn situaţia unei legături lente Icircn cazul unei legături

rapide confirmările vor veni repede şi icircntacircrzierea introdusă de algoritm va neglijabilă

Există icircnsă şi cazuri icircn care acest algoritm duce la deprecierea performanţelor mesajele scurte

generate de mişcările mouse-ului icircn cazul folosirii unui server X Window sau utilizarea tastelor

care trimit mai mult de un caracter (secvenţe escape) Pentru a rezolva aceste inconveninte API-

ul de utilizare a TCP-ului trebuie să ofere o modalitate de a dezactiva acest algoritm (icircn sistemele

bazate pe sockeţi există icircn acest scop opţiunea TCP_NODELAY)

Footnotes

algoritm3

Algoritmul aparţinacircnd lui John Nagle a fost propus icircn ianuarie 1984 icircn RFC 896

Fereastra glisantă

Algoritmul implementat de TCP pentru a implementa transferul sigur de date este cunoscut icircn

teorie sub numele de Go-Back-N Icircn acest algoritm se utilizează numere de secvenţă pentru a

distinge pachetele icircntre ele şi o coadă (dimensiunea maximă a cozii reprezintă fereastra) de

pachetele a căror confirmare se aşteaptă Pachetele se icircmpart icircn 4 categorii

1 pachete trimis şi pentru care s-a primit confirmare

2 pachete trimise şi pentru care se aşteaptă icircncă confirmarea

3 pachete care nu au fost trimise icircncă dar care nu depăşesc limitele ferestrei şi deci pot fi

trimise

4 pachete care icircncă nu au fost trimite şi care nici nu vor putea fi trimise decacirct după ce au

fost trimise toate pachetele din categoria 3 şi s-au primit o parte din confirmările la

pachetele din categoria 2

Dacă confirmările pentru pachetele din categoria 2 icircntacircrzie prea mult (un mecanism de timer-e

informează asupra acestui lucru) atunci ele vor fi retrimise Icircn versiunea iniţială TCP-ul nu

permitea decacirct confirmări pozitive ceea ce icircnseamnă că avansarea ferestrei se va icircmpotmoli la

segmentele neconfirmate Cum se poate evita aceasta situaţie vom discuta icircn detaliu icircn capitolele

următoare O soluţie foarte radicală o constituie introducerea de confirmări selective (acest lucru

este realizat de RFC 2018 din octombrie 1996) Această modifică face ca TCP-ul actual să fie un

hibrid de Go-Back-N şi Selective Repeat

Deoarece dimensiunea ferestrei este anunţată la fiecare segment un client lent poate ca pe măsură

ce trimite confirmările să informeze despre progresul icircnregistrat la livrarea datelor următorului

nivel (aplicaţie) Dacă datele vin prea repede pentru viteza cu care clientul procesează datele

fereastra fereastra se va dimiua şi chiar icircnchide (acest lucru se realizează anunţacircnd o fereastră de

dimensiune zero) Cum se realizează efectiv redeschiderea vom analiza icircntr-un capitol viitor

Slow start

Un transfer de date TCP poate să icircnceapă prin transmiterea de segmente pacircnă la umplerea

icircntregii ferestre după care fie se primesc confirmări care vor permite unor noi pachete să fie

trimise fie vor expira timer-ele de retransmisie şi se va icircncepe retrimiterea pachetelor de la

icircnceputul ferestrei Din păcate un astfel de comportament poate duce la pomparea icircn reţea a unui

număr de pachete prea mare pentru capacitatea disponibilă efectiv icircnrăutăţind congestia Pentru

a evita acest lucru s-a propus următoarea soluţie4 iniţial se trimite un segment după primirea

confirmării lui se trimit două segmente după sosirea confirmărilor pentru ele se trimit patru

segmente şi aşa mai departe La un moment dat fie vor icircncepe să se piardă segmente (un indiciu

că s-a atins capacitatea maximă a canalului) fie se va umple fereastra pe care o anunţă cel care

primeşte Trebuie să remarcam că datorită creşterii exponenţiale a numărului de segmente se va

atinge destul de repede una din cele două situaţii

Modalitatea efectivă de implementare a acestui algoritm are la bază utilizarea unei ferestre de

congestie (congestion window cwnd) care este iniţializată cu dimensiunea unui segment (cwnd

se calculează icircn octeţi) şi la fiecare pas este dublată fereastra efectivă din cadrul căreia se pot

trimite segmente este dată de minimul dintre ultima fereastra comunicată de partener şi cwnd

Footnotes

soluţie4

Soluţia aparţine lui V Jacobson şi a fost prezentată icircn 1988 la conferinţă ACM

SIGCOMM-88

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Deoarece TCP trebuie să funcţioneze icircn condiţii variate de latenţă modul icircn care se face

retransmiterea trebuie să fie cacirct mai flexibil (şi simplu icircn acelaşi timp pentru a introduce un

overhead cacirct mai mic) Timpul cacirct se aşteaptă venirea unei confirmări (retransmission timeout

RTO) este calculat prin cronometrarea timpului care icirci ia unui segment trimis să fie confirmat

Pentru o anumită conexiune se cronometrează cacircte un singur segment la un moment dat iar pe

baza RTT-ului măsurat se actualizează valoare RTO-ului

Icircn RFC 793 formula de calcul a RTO-ului este următoarea

unde este ultimul RTT măsurat este o estimare ponderată pentru RTT este un coeficient

de ponderare care icircn general are valoarea iar este un coeficient cu o valoare recomandată

de După cum se poate observa icircn valoarea lui este inclusă icircn mare măsură vechea valoarea

Icircn acest fel ajustarea RTT-ului se face treptat Din păcate acest mod de calcul nu funcţionează

bine la variaţii mari ale RTT-ului ducacircnd la creşterea numărului de retransmisii exact atunci

cacircnd fenomenul de congestie icircncepe să apară

Pentru a remedia aceste neajunsuri V Jacobsen a propus icircn 1988 o nouă metodă de calcul o

metodă care ţine seama seamă şi de modul icircn care variază diferenţa dintre RTT-uri Formulele

folosite sunt următoarele

unde este un estimare pentru media RTT-urilor este o estimare pentru abaterea RTT-urilor

faţă de medie (o aproximaţie suficientă pentru abaterea pătratică medie care icircnsă este mult mai

costisitor de calculat) este diferenţa dintre RTT-ul măsurat ( ) şi estimarea curentă ( )

Coeficientul cu care este actualizată estimarea curentă are valoarea de iar cel cu care este

actualizat estimarea abaterii este La stabilirea unei conexiuni valorile pentru şi sunt

alese astfel icircncacirct să rezulte un RTT de secunde şi un de 3 secunde (aceste recomandări

sunt făcute de RFC 1122)

Dacă pentru un anumit segment nu se primeşte confirmarea icircn intervalul indicat de el va fi

retrimis şi noul este dublat Valoarea maximă admisă pentru este de 240 secunde

Deoarece icircn cazul retrimiterilor nu se poate determina cu exactitate căruia din segmentele trimise

aparţine confirmarea actualizarea estimărilor este amacircnată pacircnă cacircnd se reuşeşte trimiterea

corectă (s-a primit confirmare) fără retransmitere(``din prima) a unui segment Acest artificiu

(deloc neimportant) care permite evitarea actualizarea eronată a estimărilor este cunoscut sub

numele de algoritmul lui Karn şi a fost propus icircn 1987 de P Karn şi C Partridge

Evitarea congestiei

Dacă cei doi parteneri care comunică prelucrează datele suficient de repede şi vor să transfere un

volum mare de date atunci limitarea de care se vor lovi este cea dată de viteza reţelei Din cauza

modului ``best-effort pe care IP-ul icircl oferă cacircnd canalul de comunicaţie este saturat o parte din

segmentele TCP se vor pierde Icircn mod poate paradoxal atacirct transmiţătorului cacirct şi receptorul se

pot afla icircn poziţia de a fi primii icircn detectarea pierderii unui segment Unul din indiciile de la

transmiţător care semnalează pierderea unui segment este (icircn mod evident) apariţia 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 icircn varianta iniţială nu

permite decacirct confirmări pozitive singurul lucru pe care receptorul icircl poate face este ca la fiecare

segment out-of-order primit să trimită o confirmare indicacircnd prin aceasta că la el continuă să

vină segmente icircnsă cel indicat de numărul de secvenţă de confirmare lipseşte Primirea acestor

confirmări multiple este al doilea mod icircn care transmiţătorul poate afla de apariţia congestiei

Algoritmul ce trebuie aplicat icircn momentul icircn care se detectează apariţia congestiei este cunoscut

sub numele de ``evitarea congestiei (congestion avoidence) Principiul care stă la baza lui este

ca la apariţia congestiei fie să se treacă la o incrementare liniară a dimensiunii ferestrei dacă

congestia a fost detectată ca urmare a primirii unor confirmări identice repetate fie să se reia

slow start-ul icircn cazul icircn care congestia s-a detectat prin expirarea unui timer de timeout

Implementarea acestui algoritm se bazează pe utilizarea unui nou contor (sstresh) care să indice

dimensiunea ferestrei de la care se trece de la incrementarea exponenţială la cea liniară

Algoritmul efectiv este următorul

1 la stabilirea unei noi conexiuni se pleacă cu sstresh iniţializat la valoare de 64K şi cwnd

la dimensiunea unui segment

2 trimiterea de segmente se face fără a depăşi minimul dintre fereastra publicată de partener

(pentru a nu depăşi capacitatea de procesesare a partenerului) şi cwnd-ul curent (pentru a

nu depăşi limita impusă de capacitatea reţelei)

3 la apariţia congestiei sstresh este setat la jumătatea valorii ferestrei curente (minimul

dintre fereastra anunţată de partener şi cwnd icircnsă cel puţin dimensiunea corespunzătoare

pentru două segmente) dacă congestia a fost detectată prin expirarea unui timer de

timeout atunci cwnd este iniţializat cu dimensiunea unui segment

4 la primirea unei confirmări incrementarea se face icircn două moduri icircn funcţie de relaţie icircn

care se află cwnd şi sstresh

1 dacă cwnd e mai mic sau egal cu sstresh se face incrementarea exponenţială

caracteristică slow start-ului (care de fapt nu e deloc slow icircn cazul de faţă)

2 dacă cwnd e mai mare ca sstresh atunci se face o incrementare cu dimensiunea

unui segment

Fast Retransmission Fast Recovery

După cum am văzut un receptor care primeşte segmente out-of-order va trimite transmiţătorului

confirmări duplicate Algoritmul denumit ``fast retransmission recomandă următoarele două

comportamenet

1 un receptor care detectează segmente out-of order trebuie să nu icircntacircrzie trimiterea de

confirmări (după cum am văzut icircn general confimările sunt icircntacircrziate micşora numărul de

pachete fără date care sunt transferate)

2 un transmiţător care care primeşte mai mult de trei confirmări duplicate trebuie să

retrimită segmentul indicat ca fiind neprimit de confirmările icircn cauză fără a aştepta

expirarea timer-ul de timeout

Algoritmul de ``fast recovery icircncearcă să optimizeze şi mai mult comportamentul

transmiţătorului care detectează un număr de trei sau mai multe confimări duplicate Mai exact el

recomandă trecerea la actualizarea liniară a ferestrei (congestion avoidance) Acest tip de

comportament se poate justifica prin următorul raţionament deoarece icircncă mai sunt transferate

date icircntre cei doi parteneri (şi acest lucru se icircntacircmplă sigur de vreme ce sosesc confirmări

duplicate icircn cazul acesta) icircnseamnă că transferul nu este afectat de o congestie severă şi prin

urmare trecerea la slow start nu e (icircncă) necesară (slow start-ul eliberează aproape complet

canalul deoarece cwnd este resetat la dimensiunea unui singur segment)

Cei doi algoritmi pot fi implementaţi icircn felul următor

1 cacircnd se detectează trei confirmări consecutive identice se setează sstresh la jumătate din

valoarea cwnd se retransmite segmentul care s-a pierdut şi se setează cwnd la valoarea

egală cu sstresh plus dimensiunea a trei segmente (acest lucru va face ca algoritmul de

incrementare a cwnd să treacă la incrementare liniară)

2 la fiecare confirmare duplicată care mai soseşte se incrementează cwnd se incrementează

cu dimensiunea unui segment

3 cacircnd icircncetează primirea de confirmări duplicate (segmentul retrimis a ajuns cu bine la

receptor şi s-a trimis o confirmare care acoperă segmentul care se pierduse iniţial) cwnd

este setat la valoarea sstresh

Sindromul ``Silly Window

Protocoalele bazate pe fereastră glisantă (cum este şi TCP-ul) pot să ajungă icircn situaţia deloc

fericită de trimite un număr mare de segmente mici icircn loc de segmente de dimensiune maximă

Acest tip de comportament este cunoscut sub numele de sindromul ``silly window

O modalitate prin care TCP-ul poate să cadă victimă acestui tip de comportament este

deschiderea de ferestre cu dimensiune foarte mică O altă situaţia nefericită este cea icircn care un

transmiţător este ``lacom şi trimite date indiferent de cacirct de mică este fereastra (după cum vom

vedea imediat uneori are sens şi un astfel de comportament) Algoritmul de evitare a acestor

neajunsuri este următorul

1 un receptor nu trebuie să anunţe deschideri de ferestre mici Mai exact nu se recomandă

anunţarea unei incrementări a ferestrei mai mică decacirct dimensiunea unui segment (MSS)

sau jumătate din buffer-ul aflat la dispoziţia receptorului oricare din ele e mai mică

2 un transmiţător va trimite date doar icircn următoarele cazuri

1 se poate trimite un segment icircntreg

2 se poate trimite jumătate din dimensiunea celei mai mari ferestre pe care

partenerul a publicat-o pacircnă acum

3 toate datele trimise pacircnă acum au fost confirmate sau algoritmul Nagle este

dezactivat şi se trimit toate datele care sunt icircn buffer-ul de trimitere

Cacircteva justificări cazul 2b tratează cazul icircn care partenerul anunţă ferestre mai mici decacirct

dimensiunea unui segment iar cazul 2c impune condiţiile respectării algoritmului Nagle după

cum se vede dacă algoritmul Nagle este activ şi s-au acumulat destul date mai exact cacirct

dimensiunea unui segment el va fi trimis chiar dacă există segmente neconfirmate Pentru

implementarea comportamentului impus de 2b un transmiţător trebuie să ţină evidenţa celei mai

mari ferestre pe care partenerul a anunţat-o Ţinacircnd seama că dimensiunea acestor buffer-e nu se

modifică acest mod de a icircncerca determinarea lor este suficient

O altă problemă legată tot de ferestre este cazul icircnchiderii acesteia Un mod icircn care s-ar putea

anunţa redeschiderea este trimiterea de către receptor a unei confirmări (duplicat) care să anunţe

redeschiderea la o anumită valoare a ferestrei Deoarece acest pachet nu trebuie confirmat icircn mod

special şi s-ar putea să se piardă se poate ajunge icircn situaţia icircn care receptorul a anunţat

redeschiderea ferestrei segmentul s-a pierdut iar transmiţătorul icircncă mai icircl mai aşteaptă pentru a

putea continua transferul Rezolvarea la această problemă s-a făcut prin impunerea unui alt

comportament

1 transmiţătorul va trimite segmente cu dimensiunea datelor de un octet prin care sondează

deschiderea ferestrei intervalul la care se sondează redeschiderea ferestrei se dublează

(exponenţial backoff) icircn RFC 793 dimensiunea maximă recomandată este de 2 minute

icircnsă icircn RFC 1122 se specifică că maximul este acelaşi cu cel din cazul retransmisiei (240

secunde)

2 receptorul trebuie să refuze aceste pachete răspunzacircnd cu segmente de confirmare care

indică neprimirea octetului respectiv

Observaţie timer-ul special necesar pentru implementare la transmiţător a comportamentului de mai sus este cunoscut sub numele de ``TCP Persistent Timer Numele este justificat de faptul că sondarea deschiderii se va face pacircnă cacircnd fie fereastra se deschide fie conexiunea se icircntrerupe TCP Keepalive Timer

Un lucru interesant despre TCP este faptul că dacă nivelele superioare nu comunică nimic icircntre

ele pentru o perioadă lungă 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 icircn care au trecut cu succes de faza stabilirii legăturii Dacă nivelurile

inferioare (reţeaIP fizic) devin temporar indisponibile cacirct tip cei doi nu vor să comunice atunci

acest lucru nu va perturba icircn nici un fel activitatea şi acest lucru este acceptabil Problemele

icircncep să apară icircn momentul icircn care cei doi doresc să comunice şi nivelele inferioare nu mai

permit acest lucru Evident că cel care va dori să comunice ceva va detecta icircntreruperea legăturii

şi va icircnchide conexiunea Ce se icircntacircmplă icircnsă dacă celălalt capăt nu are nimic de comunicat (de

exemplu este un server care oferă anumite servicii) Pentru el legătura va fi icircn continuare activă

şi icircn general anumite resurse vor fi rezervate pentru aceasta Rezolvarea acestei situaţii este dată

de introducerea unei mecanism de sondare a stării legăturii pe baza unui timer (TCP Keepalive

Timer) care se declanşează din două icircn două ore La fiecare expirare a timer-ului se trimite un

segment fără date care confirmă datele primite pacircnă atunci Răspunsul care trebuie primit este tot

un segment fără date care confirmă datele primite de partener (practic o re-publicare a stării celor

doi parteneri) Dacă răspunsul nu este primit timp de 75 secunde atunci segmentul va fi retrimis

Dacă după 10 astfel de icircncercări tot nu s-a primit nici un răspuns atunci conexiunea se va

considera terminată şi se va anunţa nivelul superior asupra acestui lucru

Observaţii

dacă o staţie primeşte segmente de keepalive despre conexiuni care nu mai sunt active

(de exemplu a fost resetat) atunci va răspunde cu segmente de reset (acesta e un procedeu

standard)

RFC 1122 specifică că facilitatea de keepalive trebuie activată icircn mod explicit

3 Studii de caz

Subsections

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

1 Fragmentarea pachetelor UDP

Deoarece UDP-ul este un serviciu fără conexiune toate datele pe care le primeşte de la nivelul

superior sunt icircncapsulate icircntr-o singură datagramă UDP care apoi va forma un pachet IP Dacă

pachetul IP astfel obţinut este prea mare atunci mecanismele IP de fragmentare icircl vor sparge icircn

bucăţi Exemplul următor icircncearcă să studieze exact acest fenomen

Pe maşina athos rulează un server de UDP pe portul 50007 Pe o altă maşină frodo aflată icircn

reţeaua locală este rulat un client care poate fi configurat să trimită un pachet UDP de o anumită

lungime Pentru a putea observa ce se icircntacircmplă pe athos este rulat tcpdump

Deoarece MTU-ul pentru o reţea Ethernet este icircn general 1500 şi antetul IP plus cel UDP ocupă

20 + 8 = 28 octeţi o datagramă UDP de dimensiune 1472 ar trebui sa fie trimisă nefragmentată

Pentru siguranţă folosind clientul de pe athos s-a trimis mai icircntacirci o datagramă UDP cu 1471

octeţi de date şi apoi icircncă una cu 1472 Pentru ambele tcpdump a indicat trimiterea lor fără

fragmentare

182556721144 frodonoi33274 gt athosnoi50007 udp 1471 (DF) (ttl 64 id

51481 len 1499)

182559846764 frodonoi33274 gt athosnoi50007 udp 1472 (DF) (ttl 64 id

51793 len 1500)

La o dimensiune de 1473 ar trebui ca trimiterea să genereze două pachete IP unul care să

conţină primii antetul UDP plus primii 1472 octeţi de date şi icircncă un pachet IP care conţine un

singur octet Iată ce indică tcpdump-ul

182605705813 frodonoi gt athosnoi udp (frag 3627411480) (ttl 64 len

21)

182605706116 frodonoi33274 gt athosnoi50007 udp 1473 (frag

3627414800+) (ttl 64 len 1500)

Intr-adevăr au fost generate două pachete IP

primul conţine doar un singur octet de date şi reprezintă ultimul fragment (bitul de more

fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest

lucru) care a fost spartă icircn bucăţi deplasamentul octetului primit in datagrama originală

este 1480

al doilea pachet este primul fragment din datagrama UDP şi conţine antetul UDP (din

cauza asta datele efective ocupă doar 1480 octeţi) deplasamentul este 0 şi bitul de more

fragments este setat (acest lucru este indicat de semnul ``+ de după deplasament)

După cum se poate observa ambele pachete poartă acelaşi număr de identificare (36274) Acest

lucru icircmpreună cu informaţiile date de flag-ul more fragments permite reconstrucţia la

destinaţie a datagramei UDP originale O problemă a acestui mod de fragmentare e că icircn cazul

pierderii unui fragment icircntreaga datagramă va fi compromisă şi va trebui retrimisă icircn icircntregime

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 12: udp tcp

trimite ACK Se observă că numărul de segmente transferate pentru realizarea icircnchiderii

conexiunii (4 segmente) este acelaşi ca la terminarea normală

3 Resetarea conexiunii

Există situaţii icircn care TCP doreşte resetarea conexiunii De exemplu dacă se solicită iniţierea

unei conexiuni la un port inexistent Icircn acest caz cealaltă parte va trimite un segment cu bitul

RST setat pentru a anula solicitarea O altă situaţie este atunci cacircnd se constată că celalalt capăt

al conexiunii nu răspunde un anumit timp (timeout)

Diagrama de stări

Toate evenimentele ce au loc icircn timpul stabilirii conexiunii transferului şi icircnchiderii conexiunii

pot fi rezumate printr-un automat finit cunoscut sub numele de diagrama de stări După cum

chiar numele sugerează este o maşină cu un număr limitat de stări O stare este păstrată pacircnă icircn

momentul apariţiei unui eveniment moment icircn care se poate trece icircn altă stare şisau efectua o

acţiune

Aceste stări posibile sunt (denumirile sunt asemănătoare cu cele utilizate de netstat) cele din

tabelul 71

Tabela Stările diagramei de stări TCP

Stare Descriere

CLOSED Nu există conexiune

LISTEN Serverul aşteaptă cereri de la clienţi

SYN_SENT Cerere de iniţiere (activă) a conexiunii Se

aşteaptă confirmarea

SYN_RCVD S-a primit o cerere de iniţiere conexiune

ESTABLISHED S-a stabilit conexiunea

FIN_WAIT_1 Aplicaţia a solicitat icircnchiderea conexiunii

FIN_WAIT_2 Serverul a acceptat icircnchiderea conexiunii

CLOSING Ambele părţi solicită simultan icircnchiderea

conexiunii

TIME_WAIT Conexiune icircnchisă dar se aşteaptă ca

pachetele retransmise să dispară

CLOSE_WAIT Serverul aşteaptă icircnchiderea dinspre partea

aplicaţiei

LAST_ACK Serverul a icircnchis conexiunea Aşteaptă

ultima confirmare

Icircn diagrama ilustrată icircn figura 74 putem observa 3 tipuri de tranziţii icircntre cele 11 stări tranziţii

ce corespund unei funcţionări normale pentru client (linii normale continue) pentru server (linii

normale icircntrerupte) şi tranziţii pentru situaţii nestandard (linii subţiri continue)

O comportarea normală pentru client presupune parcurgerea următoarelor stări CLOSED

SYN_SEND ESTABLISHED FIN_WAY_1 FIN_WAY_2 TIME_WAIT

Iniţial clientul TCP se află icircn starea CLOSED

Aşteptacircnd icircn starea CLOSED clientul poate primi de la aplicaţie o cerere de iniţiere

activă a unei conexiuni Trimite un segment SYN şi trece icircn starea SYN_SENT

Icircn starea SYN_SENT clientul aşteaptă de la server un segment ACK+SYN după care

trimite un ACK şi trece icircn starea ESTABLISHED Din acest moment poate icircncepe

transferul efectiv de date Clientul va rămacircne icircn această stare cacirct timp are de trimisprimit

date

Aflat icircn această stare clientul TCP poate primi din partea aplicaţiei o cerere de icircnchidere a

conexiunii Icircn acest caz va trimit un segment FIN şi trece icircn starea FIN_WAIT_1

Icircn această stare clientul aşteaptă ACK din partea serverului După ce-l primeşte

conexiunea icircntr-un sens se va icircnchide şi clientul trece icircn starea FIN_WAIT_2

Starea FIN_WAIT_2 durează pacircnă cacircnd primeşte cererea de icircnchidere a conexiunii FIN

din partea serverului Trimite ACK şi va trece icircn starea TIME_WAIT

Icircn această stare se va porni un timer cu valoarea setată la dublul timpului de viaţă estimat

pentru un segment de lungime maximă MSL (Maximum Segment Lifetime) Acest timer

permite retransmiterea ACK-ului icircn cazul icircn care acesta se pierde (celălalt capăt va da

timeout şi va retransmite segmentul FIN) Icircn tot acest time cei doi sockeţi (de la client şi

server) nu vor putea fi reutilizaţi Totodată pachetele icircntacircrziate care sosesc icircn această

perioadă sunt ignorate După expirarea acestui timer clientul revine icircn starea iniţială

CLOSED

Din punctul de vedere al unui server o comportare standard parcurge următoarele stări

CLOSED LISTEN SYN_RCVD ESTABLISHED CLOSE_WAIT şi LAST_ACK

Iniţial serverul TCP se află icircn starea CLOSED

Icircn această stare poate primi de la aplicaţia server o cerere de iniţiere activă şi trece icircn

starea LISTEN

Aflat icircn starea LISTEN serverului TCP poate recepţiona un segment SYN de la un client

TCP Icircn acest caz va trimite ACK+SYN şi va trece icircn starea SYN_RCVD

Icircn această stare serverul aşteaptă primirea confirmării de la client moment icircn care

conexiunea e stabilită icircn ambele sensuri şi se poate icircncepe transferul de date (starea

ESTABLISHED)

Clientul TCP poate solicita icircnchiderea conexiunii trimiţacircnd un segment FIN către server

Icircn acest caz serverul TCP trimite confirmarea şi trece icircn starea CLOSE_WAIT

Icircn această stare serverul aşteaptă să primească din partea programului server icircnchiderea

conexiunii moment icircn care va trimite către client un segment FIN şi trece icircn starea

LAST_ACK

Serverul aşteaptă primirea ultimei confirmări de la client după care revine icircn starea

CLOSED

Atacirct serverul cacirct şi clientul TCP se pot afla icircn oricare din cele 11 stări ale diagramei

Figura Diagrama de stări pentru TCP

4 Controlul fluxului

Dacă icircncă de la icircnceput s-a reuşit stabilirea formatului unui pachet TCP şi a modulului icircn care

trebuie să se facă icircnchiderea şi deschiderea unei conexiuni nu acelaşi lucru se poate spune şi

despre modul icircn care ar trebui să se realizeze controlul fluxului Ţinacircnd seama icircnsă că din 1989

(de cacircnd datează RFC-ul 2581 cel despre care am menţionat că specifică icircn mod clar modul icircn

care trebuie să se comporte o implementare de TCP) TCP-ul a rămas neschimbat putem să icircl

considerăm un rezultat important al domeniului reţelor de calculatoare

Icircn cele ce urmează vom icircnţelege prin controlul fluxului totalitatea algoritmilor care permit

atingerea unei viteze de transfer punct-la-punct cacirct mai mare pentru toate conexiunile existente

Icircn principal aceşti algoritmi stabilesc modul icircn care segmentele şi confirmările trebuie trimise şi

ce acţiuni trebuie executate icircn situaţiile icircn care răspunsurile aşteptate de la celălalt capăt icircntacircrzie

să vină

Subsections

Icircntacircrzierea confirmărilor

Algoritmul Nagle

Fereastra glisantă

Slow start

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Evitarea congestiei

Fast Retransmission Fast Recovery

Sindromul ``Silly Window

TCP Keepalive Timer

Icircntacircrzierea confirmărilor

O modalitate simplă de generare a confirmărilor este de a trimite cacircte una pentru fiecare segment

primit Această politică prezintă avantajul de a face comunicaţia self-clocking icircnsă este

ineficientă dacă segmentele care nu conţin decacirct confirmări sunt urmate la scurtă distanţă (cacircteva

zeci de milisecunde) de segmente ce conţin date efective Pentru a evita această situaţie se

procedează2 la icircntacircrzierea (200ms este o valoare uzuală icircn RFC 1122 se specifică o valoare

maximă de 500ms) a segmentelor care conţin doar confirmări Această strategie face posibil ca

un răspuns generat de primirea unor date să plece sper celălalt capăt icircn acelaşi segment cu

confirmarea

Observaţie deoarece este dificil de menţinut timere pentru fiecare confirmare diferenţa de

200ms este calculată de un timer global Din acest motiv modul efectiv de comportare poate fi

descris şi icircn felul următor cacircnd un segment nu conţine decacirct o confirmare el este pus icircntr-o

coadă ce va fi inspectată de un proces care din 200 icircn 200 ms trimite tot ce s-a acumulat icircn

coada

Footnotes

2

Acest comportament a fost propus de David D Clark icircn iulie 1982 icircn RFC 813

Algoritmul Nagle

Acest algoritm3 icircncearcă să icircmbunătăţească performanţele exploatacircnd următoarea caracteristică

foarte des icircntacirclnită icircn dialogul dintre două staţii dacă se icircncearcă trimiterea unor date de

dimensiune mică icircnsă există icircncă date neconfirmate de partener atunci ele sunt buffer-ate şi

trimise icircntr-un segment mai mare cacircnd soseşte confirmarea aşteptată Icircn acest fel se poate evita

generarea datagramelor mici (tinygrame) icircn situaţia unei legături lente Icircn cazul unei legături

rapide confirmările vor veni repede şi icircntacircrzierea introdusă de algoritm va neglijabilă

Există icircnsă şi cazuri icircn care acest algoritm duce la deprecierea performanţelor mesajele scurte

generate de mişcările mouse-ului icircn cazul folosirii unui server X Window sau utilizarea tastelor

care trimit mai mult de un caracter (secvenţe escape) Pentru a rezolva aceste inconveninte API-

ul de utilizare a TCP-ului trebuie să ofere o modalitate de a dezactiva acest algoritm (icircn sistemele

bazate pe sockeţi există icircn acest scop opţiunea TCP_NODELAY)

Footnotes

algoritm3

Algoritmul aparţinacircnd lui John Nagle a fost propus icircn ianuarie 1984 icircn RFC 896

Fereastra glisantă

Algoritmul implementat de TCP pentru a implementa transferul sigur de date este cunoscut icircn

teorie sub numele de Go-Back-N Icircn acest algoritm se utilizează numere de secvenţă pentru a

distinge pachetele icircntre ele şi o coadă (dimensiunea maximă a cozii reprezintă fereastra) de

pachetele a căror confirmare se aşteaptă Pachetele se icircmpart icircn 4 categorii

1 pachete trimis şi pentru care s-a primit confirmare

2 pachete trimise şi pentru care se aşteaptă icircncă confirmarea

3 pachete care nu au fost trimise icircncă dar care nu depăşesc limitele ferestrei şi deci pot fi

trimise

4 pachete care icircncă nu au fost trimite şi care nici nu vor putea fi trimise decacirct după ce au

fost trimise toate pachetele din categoria 3 şi s-au primit o parte din confirmările la

pachetele din categoria 2

Dacă confirmările pentru pachetele din categoria 2 icircntacircrzie prea mult (un mecanism de timer-e

informează asupra acestui lucru) atunci ele vor fi retrimise Icircn versiunea iniţială TCP-ul nu

permitea decacirct confirmări pozitive ceea ce icircnseamnă că avansarea ferestrei se va icircmpotmoli la

segmentele neconfirmate Cum se poate evita aceasta situaţie vom discuta icircn detaliu icircn capitolele

următoare O soluţie foarte radicală o constituie introducerea de confirmări selective (acest lucru

este realizat de RFC 2018 din octombrie 1996) Această modifică face ca TCP-ul actual să fie un

hibrid de Go-Back-N şi Selective Repeat

Deoarece dimensiunea ferestrei este anunţată la fiecare segment un client lent poate ca pe măsură

ce trimite confirmările să informeze despre progresul icircnregistrat la livrarea datelor următorului

nivel (aplicaţie) Dacă datele vin prea repede pentru viteza cu care clientul procesează datele

fereastra fereastra se va dimiua şi chiar icircnchide (acest lucru se realizează anunţacircnd o fereastră de

dimensiune zero) Cum se realizează efectiv redeschiderea vom analiza icircntr-un capitol viitor

Slow start

Un transfer de date TCP poate să icircnceapă prin transmiterea de segmente pacircnă la umplerea

icircntregii ferestre după care fie se primesc confirmări care vor permite unor noi pachete să fie

trimise fie vor expira timer-ele de retransmisie şi se va icircncepe retrimiterea pachetelor de la

icircnceputul ferestrei Din păcate un astfel de comportament poate duce la pomparea icircn reţea a unui

număr de pachete prea mare pentru capacitatea disponibilă efectiv icircnrăutăţind congestia Pentru

a evita acest lucru s-a propus următoarea soluţie4 iniţial se trimite un segment după primirea

confirmării lui se trimit două segmente după sosirea confirmărilor pentru ele se trimit patru

segmente şi aşa mai departe La un moment dat fie vor icircncepe să se piardă segmente (un indiciu

că s-a atins capacitatea maximă a canalului) fie se va umple fereastra pe care o anunţă cel care

primeşte Trebuie să remarcam că datorită creşterii exponenţiale a numărului de segmente se va

atinge destul de repede una din cele două situaţii

Modalitatea efectivă de implementare a acestui algoritm are la bază utilizarea unei ferestre de

congestie (congestion window cwnd) care este iniţializată cu dimensiunea unui segment (cwnd

se calculează icircn octeţi) şi la fiecare pas este dublată fereastra efectivă din cadrul căreia se pot

trimite segmente este dată de minimul dintre ultima fereastra comunicată de partener şi cwnd

Footnotes

soluţie4

Soluţia aparţine lui V Jacobson şi a fost prezentată icircn 1988 la conferinţă ACM

SIGCOMM-88

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Deoarece TCP trebuie să funcţioneze icircn condiţii variate de latenţă modul icircn care se face

retransmiterea trebuie să fie cacirct mai flexibil (şi simplu icircn acelaşi timp pentru a introduce un

overhead cacirct mai mic) Timpul cacirct se aşteaptă venirea unei confirmări (retransmission timeout

RTO) este calculat prin cronometrarea timpului care icirci ia unui segment trimis să fie confirmat

Pentru o anumită conexiune se cronometrează cacircte un singur segment la un moment dat iar pe

baza RTT-ului măsurat se actualizează valoare RTO-ului

Icircn RFC 793 formula de calcul a RTO-ului este următoarea

unde este ultimul RTT măsurat este o estimare ponderată pentru RTT este un coeficient

de ponderare care icircn general are valoarea iar este un coeficient cu o valoare recomandată

de După cum se poate observa icircn valoarea lui este inclusă icircn mare măsură vechea valoarea

Icircn acest fel ajustarea RTT-ului se face treptat Din păcate acest mod de calcul nu funcţionează

bine la variaţii mari ale RTT-ului ducacircnd la creşterea numărului de retransmisii exact atunci

cacircnd fenomenul de congestie icircncepe să apară

Pentru a remedia aceste neajunsuri V Jacobsen a propus icircn 1988 o nouă metodă de calcul o

metodă care ţine seama seamă şi de modul icircn care variază diferenţa dintre RTT-uri Formulele

folosite sunt următoarele

unde este un estimare pentru media RTT-urilor este o estimare pentru abaterea RTT-urilor

faţă de medie (o aproximaţie suficientă pentru abaterea pătratică medie care icircnsă este mult mai

costisitor de calculat) este diferenţa dintre RTT-ul măsurat ( ) şi estimarea curentă ( )

Coeficientul cu care este actualizată estimarea curentă are valoarea de iar cel cu care este

actualizat estimarea abaterii este La stabilirea unei conexiuni valorile pentru şi sunt

alese astfel icircncacirct să rezulte un RTT de secunde şi un de 3 secunde (aceste recomandări

sunt făcute de RFC 1122)

Dacă pentru un anumit segment nu se primeşte confirmarea icircn intervalul indicat de el va fi

retrimis şi noul este dublat Valoarea maximă admisă pentru este de 240 secunde

Deoarece icircn cazul retrimiterilor nu se poate determina cu exactitate căruia din segmentele trimise

aparţine confirmarea actualizarea estimărilor este amacircnată pacircnă cacircnd se reuşeşte trimiterea

corectă (s-a primit confirmare) fără retransmitere(``din prima) a unui segment Acest artificiu

(deloc neimportant) care permite evitarea actualizarea eronată a estimărilor este cunoscut sub

numele de algoritmul lui Karn şi a fost propus icircn 1987 de P Karn şi C Partridge

Evitarea congestiei

Dacă cei doi parteneri care comunică prelucrează datele suficient de repede şi vor să transfere un

volum mare de date atunci limitarea de care se vor lovi este cea dată de viteza reţelei Din cauza

modului ``best-effort pe care IP-ul icircl oferă cacircnd canalul de comunicaţie este saturat o parte din

segmentele TCP se vor pierde Icircn mod poate paradoxal atacirct transmiţătorului cacirct şi receptorul se

pot afla icircn poziţia de a fi primii icircn detectarea pierderii unui segment Unul din indiciile de la

transmiţător care semnalează pierderea unui segment este (icircn mod evident) apariţia 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 icircn varianta iniţială nu

permite decacirct confirmări pozitive singurul lucru pe care receptorul icircl poate face este ca la fiecare

segment out-of-order primit să trimită o confirmare indicacircnd prin aceasta că la el continuă să

vină segmente icircnsă cel indicat de numărul de secvenţă de confirmare lipseşte Primirea acestor

confirmări multiple este al doilea mod icircn care transmiţătorul poate afla de apariţia congestiei

Algoritmul ce trebuie aplicat icircn momentul icircn care se detectează apariţia congestiei este cunoscut

sub numele de ``evitarea congestiei (congestion avoidence) Principiul care stă la baza lui este

ca la apariţia congestiei fie să se treacă la o incrementare liniară a dimensiunii ferestrei dacă

congestia a fost detectată ca urmare a primirii unor confirmări identice repetate fie să se reia

slow start-ul icircn cazul icircn care congestia s-a detectat prin expirarea unui timer de timeout

Implementarea acestui algoritm se bazează pe utilizarea unui nou contor (sstresh) care să indice

dimensiunea ferestrei de la care se trece de la incrementarea exponenţială la cea liniară

Algoritmul efectiv este următorul

1 la stabilirea unei noi conexiuni se pleacă cu sstresh iniţializat la valoare de 64K şi cwnd

la dimensiunea unui segment

2 trimiterea de segmente se face fără a depăşi minimul dintre fereastra publicată de partener

(pentru a nu depăşi capacitatea de procesesare a partenerului) şi cwnd-ul curent (pentru a

nu depăşi limita impusă de capacitatea reţelei)

3 la apariţia congestiei sstresh este setat la jumătatea valorii ferestrei curente (minimul

dintre fereastra anunţată de partener şi cwnd icircnsă cel puţin dimensiunea corespunzătoare

pentru două segmente) dacă congestia a fost detectată prin expirarea unui timer de

timeout atunci cwnd este iniţializat cu dimensiunea unui segment

4 la primirea unei confirmări incrementarea se face icircn două moduri icircn funcţie de relaţie icircn

care se află cwnd şi sstresh

1 dacă cwnd e mai mic sau egal cu sstresh se face incrementarea exponenţială

caracteristică slow start-ului (care de fapt nu e deloc slow icircn cazul de faţă)

2 dacă cwnd e mai mare ca sstresh atunci se face o incrementare cu dimensiunea

unui segment

Fast Retransmission Fast Recovery

După cum am văzut un receptor care primeşte segmente out-of-order va trimite transmiţătorului

confirmări duplicate Algoritmul denumit ``fast retransmission recomandă următoarele două

comportamenet

1 un receptor care detectează segmente out-of order trebuie să nu icircntacircrzie trimiterea de

confirmări (după cum am văzut icircn general confimările sunt icircntacircrziate micşora numărul de

pachete fără date care sunt transferate)

2 un transmiţător care care primeşte mai mult de trei confirmări duplicate trebuie să

retrimită segmentul indicat ca fiind neprimit de confirmările icircn cauză fără a aştepta

expirarea timer-ul de timeout

Algoritmul de ``fast recovery icircncearcă să optimizeze şi mai mult comportamentul

transmiţătorului care detectează un număr de trei sau mai multe confimări duplicate Mai exact el

recomandă trecerea la actualizarea liniară a ferestrei (congestion avoidance) Acest tip de

comportament se poate justifica prin următorul raţionament deoarece icircncă mai sunt transferate

date icircntre cei doi parteneri (şi acest lucru se icircntacircmplă sigur de vreme ce sosesc confirmări

duplicate icircn cazul acesta) icircnseamnă că transferul nu este afectat de o congestie severă şi prin

urmare trecerea la slow start nu e (icircncă) necesară (slow start-ul eliberează aproape complet

canalul deoarece cwnd este resetat la dimensiunea unui singur segment)

Cei doi algoritmi pot fi implementaţi icircn felul următor

1 cacircnd se detectează trei confirmări consecutive identice se setează sstresh la jumătate din

valoarea cwnd se retransmite segmentul care s-a pierdut şi se setează cwnd la valoarea

egală cu sstresh plus dimensiunea a trei segmente (acest lucru va face ca algoritmul de

incrementare a cwnd să treacă la incrementare liniară)

2 la fiecare confirmare duplicată care mai soseşte se incrementează cwnd se incrementează

cu dimensiunea unui segment

3 cacircnd icircncetează primirea de confirmări duplicate (segmentul retrimis a ajuns cu bine la

receptor şi s-a trimis o confirmare care acoperă segmentul care se pierduse iniţial) cwnd

este setat la valoarea sstresh

Sindromul ``Silly Window

Protocoalele bazate pe fereastră glisantă (cum este şi TCP-ul) pot să ajungă icircn situaţia deloc

fericită de trimite un număr mare de segmente mici icircn loc de segmente de dimensiune maximă

Acest tip de comportament este cunoscut sub numele de sindromul ``silly window

O modalitate prin care TCP-ul poate să cadă victimă acestui tip de comportament este

deschiderea de ferestre cu dimensiune foarte mică O altă situaţia nefericită este cea icircn care un

transmiţător este ``lacom şi trimite date indiferent de cacirct de mică este fereastra (după cum vom

vedea imediat uneori are sens şi un astfel de comportament) Algoritmul de evitare a acestor

neajunsuri este următorul

1 un receptor nu trebuie să anunţe deschideri de ferestre mici Mai exact nu se recomandă

anunţarea unei incrementări a ferestrei mai mică decacirct dimensiunea unui segment (MSS)

sau jumătate din buffer-ul aflat la dispoziţia receptorului oricare din ele e mai mică

2 un transmiţător va trimite date doar icircn următoarele cazuri

1 se poate trimite un segment icircntreg

2 se poate trimite jumătate din dimensiunea celei mai mari ferestre pe care

partenerul a publicat-o pacircnă acum

3 toate datele trimise pacircnă acum au fost confirmate sau algoritmul Nagle este

dezactivat şi se trimit toate datele care sunt icircn buffer-ul de trimitere

Cacircteva justificări cazul 2b tratează cazul icircn care partenerul anunţă ferestre mai mici decacirct

dimensiunea unui segment iar cazul 2c impune condiţiile respectării algoritmului Nagle după

cum se vede dacă algoritmul Nagle este activ şi s-au acumulat destul date mai exact cacirct

dimensiunea unui segment el va fi trimis chiar dacă există segmente neconfirmate Pentru

implementarea comportamentului impus de 2b un transmiţător trebuie să ţină evidenţa celei mai

mari ferestre pe care partenerul a anunţat-o Ţinacircnd seama că dimensiunea acestor buffer-e nu se

modifică acest mod de a icircncerca determinarea lor este suficient

O altă problemă legată tot de ferestre este cazul icircnchiderii acesteia Un mod icircn care s-ar putea

anunţa redeschiderea este trimiterea de către receptor a unei confirmări (duplicat) care să anunţe

redeschiderea la o anumită valoare a ferestrei Deoarece acest pachet nu trebuie confirmat icircn mod

special şi s-ar putea să se piardă se poate ajunge icircn situaţia icircn care receptorul a anunţat

redeschiderea ferestrei segmentul s-a pierdut iar transmiţătorul icircncă mai icircl mai aşteaptă pentru a

putea continua transferul Rezolvarea la această problemă s-a făcut prin impunerea unui alt

comportament

1 transmiţătorul va trimite segmente cu dimensiunea datelor de un octet prin care sondează

deschiderea ferestrei intervalul la care se sondează redeschiderea ferestrei se dublează

(exponenţial backoff) icircn RFC 793 dimensiunea maximă recomandată este de 2 minute

icircnsă icircn RFC 1122 se specifică că maximul este acelaşi cu cel din cazul retransmisiei (240

secunde)

2 receptorul trebuie să refuze aceste pachete răspunzacircnd cu segmente de confirmare care

indică neprimirea octetului respectiv

Observaţie timer-ul special necesar pentru implementare la transmiţător a comportamentului de mai sus este cunoscut sub numele de ``TCP Persistent Timer Numele este justificat de faptul că sondarea deschiderii se va face pacircnă cacircnd fie fereastra se deschide fie conexiunea se icircntrerupe TCP Keepalive Timer

Un lucru interesant despre TCP este faptul că dacă nivelele superioare nu comunică nimic icircntre

ele pentru o perioadă lungă 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 icircn care au trecut cu succes de faza stabilirii legăturii Dacă nivelurile

inferioare (reţeaIP fizic) devin temporar indisponibile cacirct tip cei doi nu vor să comunice atunci

acest lucru nu va perturba icircn nici un fel activitatea şi acest lucru este acceptabil Problemele

icircncep să apară icircn momentul icircn care cei doi doresc să comunice şi nivelele inferioare nu mai

permit acest lucru Evident că cel care va dori să comunice ceva va detecta icircntreruperea legăturii

şi va icircnchide conexiunea Ce se icircntacircmplă icircnsă dacă celălalt capăt nu are nimic de comunicat (de

exemplu este un server care oferă anumite servicii) Pentru el legătura va fi icircn continuare activă

şi icircn general anumite resurse vor fi rezervate pentru aceasta Rezolvarea acestei situaţii este dată

de introducerea unei mecanism de sondare a stării legăturii pe baza unui timer (TCP Keepalive

Timer) care se declanşează din două icircn două ore La fiecare expirare a timer-ului se trimite un

segment fără date care confirmă datele primite pacircnă atunci Răspunsul care trebuie primit este tot

un segment fără date care confirmă datele primite de partener (practic o re-publicare a stării celor

doi parteneri) Dacă răspunsul nu este primit timp de 75 secunde atunci segmentul va fi retrimis

Dacă după 10 astfel de icircncercări tot nu s-a primit nici un răspuns atunci conexiunea se va

considera terminată şi se va anunţa nivelul superior asupra acestui lucru

Observaţii

dacă o staţie primeşte segmente de keepalive despre conexiuni care nu mai sunt active

(de exemplu a fost resetat) atunci va răspunde cu segmente de reset (acesta e un procedeu

standard)

RFC 1122 specifică că facilitatea de keepalive trebuie activată icircn mod explicit

3 Studii de caz

Subsections

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

1 Fragmentarea pachetelor UDP

Deoarece UDP-ul este un serviciu fără conexiune toate datele pe care le primeşte de la nivelul

superior sunt icircncapsulate icircntr-o singură datagramă UDP care apoi va forma un pachet IP Dacă

pachetul IP astfel obţinut este prea mare atunci mecanismele IP de fragmentare icircl vor sparge icircn

bucăţi Exemplul următor icircncearcă să studieze exact acest fenomen

Pe maşina athos rulează un server de UDP pe portul 50007 Pe o altă maşină frodo aflată icircn

reţeaua locală este rulat un client care poate fi configurat să trimită un pachet UDP de o anumită

lungime Pentru a putea observa ce se icircntacircmplă pe athos este rulat tcpdump

Deoarece MTU-ul pentru o reţea Ethernet este icircn general 1500 şi antetul IP plus cel UDP ocupă

20 + 8 = 28 octeţi o datagramă UDP de dimensiune 1472 ar trebui sa fie trimisă nefragmentată

Pentru siguranţă folosind clientul de pe athos s-a trimis mai icircntacirci o datagramă UDP cu 1471

octeţi de date şi apoi icircncă una cu 1472 Pentru ambele tcpdump a indicat trimiterea lor fără

fragmentare

182556721144 frodonoi33274 gt athosnoi50007 udp 1471 (DF) (ttl 64 id

51481 len 1499)

182559846764 frodonoi33274 gt athosnoi50007 udp 1472 (DF) (ttl 64 id

51793 len 1500)

La o dimensiune de 1473 ar trebui ca trimiterea să genereze două pachete IP unul care să

conţină primii antetul UDP plus primii 1472 octeţi de date şi icircncă un pachet IP care conţine un

singur octet Iată ce indică tcpdump-ul

182605705813 frodonoi gt athosnoi udp (frag 3627411480) (ttl 64 len

21)

182605706116 frodonoi33274 gt athosnoi50007 udp 1473 (frag

3627414800+) (ttl 64 len 1500)

Intr-adevăr au fost generate două pachete IP

primul conţine doar un singur octet de date şi reprezintă ultimul fragment (bitul de more

fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest

lucru) care a fost spartă icircn bucăţi deplasamentul octetului primit in datagrama originală

este 1480

al doilea pachet este primul fragment din datagrama UDP şi conţine antetul UDP (din

cauza asta datele efective ocupă doar 1480 octeţi) deplasamentul este 0 şi bitul de more

fragments este setat (acest lucru este indicat de semnul ``+ de după deplasament)

După cum se poate observa ambele pachete poartă acelaşi număr de identificare (36274) Acest

lucru icircmpreună cu informaţiile date de flag-ul more fragments permite reconstrucţia la

destinaţie a datagramei UDP originale O problemă a acestui mod de fragmentare e că icircn cazul

pierderii unui fragment icircntreaga datagramă va fi compromisă şi va trebui retrimisă icircn icircntregime

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 13: udp tcp

Icircn diagrama ilustrată icircn figura 74 putem observa 3 tipuri de tranziţii icircntre cele 11 stări tranziţii

ce corespund unei funcţionări normale pentru client (linii normale continue) pentru server (linii

normale icircntrerupte) şi tranziţii pentru situaţii nestandard (linii subţiri continue)

O comportarea normală pentru client presupune parcurgerea următoarelor stări CLOSED

SYN_SEND ESTABLISHED FIN_WAY_1 FIN_WAY_2 TIME_WAIT

Iniţial clientul TCP se află icircn starea CLOSED

Aşteptacircnd icircn starea CLOSED clientul poate primi de la aplicaţie o cerere de iniţiere

activă a unei conexiuni Trimite un segment SYN şi trece icircn starea SYN_SENT

Icircn starea SYN_SENT clientul aşteaptă de la server un segment ACK+SYN după care

trimite un ACK şi trece icircn starea ESTABLISHED Din acest moment poate icircncepe

transferul efectiv de date Clientul va rămacircne icircn această stare cacirct timp are de trimisprimit

date

Aflat icircn această stare clientul TCP poate primi din partea aplicaţiei o cerere de icircnchidere a

conexiunii Icircn acest caz va trimit un segment FIN şi trece icircn starea FIN_WAIT_1

Icircn această stare clientul aşteaptă ACK din partea serverului După ce-l primeşte

conexiunea icircntr-un sens se va icircnchide şi clientul trece icircn starea FIN_WAIT_2

Starea FIN_WAIT_2 durează pacircnă cacircnd primeşte cererea de icircnchidere a conexiunii FIN

din partea serverului Trimite ACK şi va trece icircn starea TIME_WAIT

Icircn această stare se va porni un timer cu valoarea setată la dublul timpului de viaţă estimat

pentru un segment de lungime maximă MSL (Maximum Segment Lifetime) Acest timer

permite retransmiterea ACK-ului icircn cazul icircn care acesta se pierde (celălalt capăt va da

timeout şi va retransmite segmentul FIN) Icircn tot acest time cei doi sockeţi (de la client şi

server) nu vor putea fi reutilizaţi Totodată pachetele icircntacircrziate care sosesc icircn această

perioadă sunt ignorate După expirarea acestui timer clientul revine icircn starea iniţială

CLOSED

Din punctul de vedere al unui server o comportare standard parcurge următoarele stări

CLOSED LISTEN SYN_RCVD ESTABLISHED CLOSE_WAIT şi LAST_ACK

Iniţial serverul TCP se află icircn starea CLOSED

Icircn această stare poate primi de la aplicaţia server o cerere de iniţiere activă şi trece icircn

starea LISTEN

Aflat icircn starea LISTEN serverului TCP poate recepţiona un segment SYN de la un client

TCP Icircn acest caz va trimite ACK+SYN şi va trece icircn starea SYN_RCVD

Icircn această stare serverul aşteaptă primirea confirmării de la client moment icircn care

conexiunea e stabilită icircn ambele sensuri şi se poate icircncepe transferul de date (starea

ESTABLISHED)

Clientul TCP poate solicita icircnchiderea conexiunii trimiţacircnd un segment FIN către server

Icircn acest caz serverul TCP trimite confirmarea şi trece icircn starea CLOSE_WAIT

Icircn această stare serverul aşteaptă să primească din partea programului server icircnchiderea

conexiunii moment icircn care va trimite către client un segment FIN şi trece icircn starea

LAST_ACK

Serverul aşteaptă primirea ultimei confirmări de la client după care revine icircn starea

CLOSED

Atacirct serverul cacirct şi clientul TCP se pot afla icircn oricare din cele 11 stări ale diagramei

Figura Diagrama de stări pentru TCP

4 Controlul fluxului

Dacă icircncă de la icircnceput s-a reuşit stabilirea formatului unui pachet TCP şi a modulului icircn care

trebuie să se facă icircnchiderea şi deschiderea unei conexiuni nu acelaşi lucru se poate spune şi

despre modul icircn care ar trebui să se realizeze controlul fluxului Ţinacircnd seama icircnsă că din 1989

(de cacircnd datează RFC-ul 2581 cel despre care am menţionat că specifică icircn mod clar modul icircn

care trebuie să se comporte o implementare de TCP) TCP-ul a rămas neschimbat putem să icircl

considerăm un rezultat important al domeniului reţelor de calculatoare

Icircn cele ce urmează vom icircnţelege prin controlul fluxului totalitatea algoritmilor care permit

atingerea unei viteze de transfer punct-la-punct cacirct mai mare pentru toate conexiunile existente

Icircn principal aceşti algoritmi stabilesc modul icircn care segmentele şi confirmările trebuie trimise şi

ce acţiuni trebuie executate icircn situaţiile icircn care răspunsurile aşteptate de la celălalt capăt icircntacircrzie

să vină

Subsections

Icircntacircrzierea confirmărilor

Algoritmul Nagle

Fereastra glisantă

Slow start

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Evitarea congestiei

Fast Retransmission Fast Recovery

Sindromul ``Silly Window

TCP Keepalive Timer

Icircntacircrzierea confirmărilor

O modalitate simplă de generare a confirmărilor este de a trimite cacircte una pentru fiecare segment

primit Această politică prezintă avantajul de a face comunicaţia self-clocking icircnsă este

ineficientă dacă segmentele care nu conţin decacirct confirmări sunt urmate la scurtă distanţă (cacircteva

zeci de milisecunde) de segmente ce conţin date efective Pentru a evita această situaţie se

procedează2 la icircntacircrzierea (200ms este o valoare uzuală icircn RFC 1122 se specifică o valoare

maximă de 500ms) a segmentelor care conţin doar confirmări Această strategie face posibil ca

un răspuns generat de primirea unor date să plece sper celălalt capăt icircn acelaşi segment cu

confirmarea

Observaţie deoarece este dificil de menţinut timere pentru fiecare confirmare diferenţa de

200ms este calculată de un timer global Din acest motiv modul efectiv de comportare poate fi

descris şi icircn felul următor cacircnd un segment nu conţine decacirct o confirmare el este pus icircntr-o

coadă ce va fi inspectată de un proces care din 200 icircn 200 ms trimite tot ce s-a acumulat icircn

coada

Footnotes

2

Acest comportament a fost propus de David D Clark icircn iulie 1982 icircn RFC 813

Algoritmul Nagle

Acest algoritm3 icircncearcă să icircmbunătăţească performanţele exploatacircnd următoarea caracteristică

foarte des icircntacirclnită icircn dialogul dintre două staţii dacă se icircncearcă trimiterea unor date de

dimensiune mică icircnsă există icircncă date neconfirmate de partener atunci ele sunt buffer-ate şi

trimise icircntr-un segment mai mare cacircnd soseşte confirmarea aşteptată Icircn acest fel se poate evita

generarea datagramelor mici (tinygrame) icircn situaţia unei legături lente Icircn cazul unei legături

rapide confirmările vor veni repede şi icircntacircrzierea introdusă de algoritm va neglijabilă

Există icircnsă şi cazuri icircn care acest algoritm duce la deprecierea performanţelor mesajele scurte

generate de mişcările mouse-ului icircn cazul folosirii unui server X Window sau utilizarea tastelor

care trimit mai mult de un caracter (secvenţe escape) Pentru a rezolva aceste inconveninte API-

ul de utilizare a TCP-ului trebuie să ofere o modalitate de a dezactiva acest algoritm (icircn sistemele

bazate pe sockeţi există icircn acest scop opţiunea TCP_NODELAY)

Footnotes

algoritm3

Algoritmul aparţinacircnd lui John Nagle a fost propus icircn ianuarie 1984 icircn RFC 896

Fereastra glisantă

Algoritmul implementat de TCP pentru a implementa transferul sigur de date este cunoscut icircn

teorie sub numele de Go-Back-N Icircn acest algoritm se utilizează numere de secvenţă pentru a

distinge pachetele icircntre ele şi o coadă (dimensiunea maximă a cozii reprezintă fereastra) de

pachetele a căror confirmare se aşteaptă Pachetele se icircmpart icircn 4 categorii

1 pachete trimis şi pentru care s-a primit confirmare

2 pachete trimise şi pentru care se aşteaptă icircncă confirmarea

3 pachete care nu au fost trimise icircncă dar care nu depăşesc limitele ferestrei şi deci pot fi

trimise

4 pachete care icircncă nu au fost trimite şi care nici nu vor putea fi trimise decacirct după ce au

fost trimise toate pachetele din categoria 3 şi s-au primit o parte din confirmările la

pachetele din categoria 2

Dacă confirmările pentru pachetele din categoria 2 icircntacircrzie prea mult (un mecanism de timer-e

informează asupra acestui lucru) atunci ele vor fi retrimise Icircn versiunea iniţială TCP-ul nu

permitea decacirct confirmări pozitive ceea ce icircnseamnă că avansarea ferestrei se va icircmpotmoli la

segmentele neconfirmate Cum se poate evita aceasta situaţie vom discuta icircn detaliu icircn capitolele

următoare O soluţie foarte radicală o constituie introducerea de confirmări selective (acest lucru

este realizat de RFC 2018 din octombrie 1996) Această modifică face ca TCP-ul actual să fie un

hibrid de Go-Back-N şi Selective Repeat

Deoarece dimensiunea ferestrei este anunţată la fiecare segment un client lent poate ca pe măsură

ce trimite confirmările să informeze despre progresul icircnregistrat la livrarea datelor următorului

nivel (aplicaţie) Dacă datele vin prea repede pentru viteza cu care clientul procesează datele

fereastra fereastra se va dimiua şi chiar icircnchide (acest lucru se realizează anunţacircnd o fereastră de

dimensiune zero) Cum se realizează efectiv redeschiderea vom analiza icircntr-un capitol viitor

Slow start

Un transfer de date TCP poate să icircnceapă prin transmiterea de segmente pacircnă la umplerea

icircntregii ferestre după care fie se primesc confirmări care vor permite unor noi pachete să fie

trimise fie vor expira timer-ele de retransmisie şi se va icircncepe retrimiterea pachetelor de la

icircnceputul ferestrei Din păcate un astfel de comportament poate duce la pomparea icircn reţea a unui

număr de pachete prea mare pentru capacitatea disponibilă efectiv icircnrăutăţind congestia Pentru

a evita acest lucru s-a propus următoarea soluţie4 iniţial se trimite un segment după primirea

confirmării lui se trimit două segmente după sosirea confirmărilor pentru ele se trimit patru

segmente şi aşa mai departe La un moment dat fie vor icircncepe să se piardă segmente (un indiciu

că s-a atins capacitatea maximă a canalului) fie se va umple fereastra pe care o anunţă cel care

primeşte Trebuie să remarcam că datorită creşterii exponenţiale a numărului de segmente se va

atinge destul de repede una din cele două situaţii

Modalitatea efectivă de implementare a acestui algoritm are la bază utilizarea unei ferestre de

congestie (congestion window cwnd) care este iniţializată cu dimensiunea unui segment (cwnd

se calculează icircn octeţi) şi la fiecare pas este dublată fereastra efectivă din cadrul căreia se pot

trimite segmente este dată de minimul dintre ultima fereastra comunicată de partener şi cwnd

Footnotes

soluţie4

Soluţia aparţine lui V Jacobson şi a fost prezentată icircn 1988 la conferinţă ACM

SIGCOMM-88

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Deoarece TCP trebuie să funcţioneze icircn condiţii variate de latenţă modul icircn care se face

retransmiterea trebuie să fie cacirct mai flexibil (şi simplu icircn acelaşi timp pentru a introduce un

overhead cacirct mai mic) Timpul cacirct se aşteaptă venirea unei confirmări (retransmission timeout

RTO) este calculat prin cronometrarea timpului care icirci ia unui segment trimis să fie confirmat

Pentru o anumită conexiune se cronometrează cacircte un singur segment la un moment dat iar pe

baza RTT-ului măsurat se actualizează valoare RTO-ului

Icircn RFC 793 formula de calcul a RTO-ului este următoarea

unde este ultimul RTT măsurat este o estimare ponderată pentru RTT este un coeficient

de ponderare care icircn general are valoarea iar este un coeficient cu o valoare recomandată

de După cum se poate observa icircn valoarea lui este inclusă icircn mare măsură vechea valoarea

Icircn acest fel ajustarea RTT-ului se face treptat Din păcate acest mod de calcul nu funcţionează

bine la variaţii mari ale RTT-ului ducacircnd la creşterea numărului de retransmisii exact atunci

cacircnd fenomenul de congestie icircncepe să apară

Pentru a remedia aceste neajunsuri V Jacobsen a propus icircn 1988 o nouă metodă de calcul o

metodă care ţine seama seamă şi de modul icircn care variază diferenţa dintre RTT-uri Formulele

folosite sunt următoarele

unde este un estimare pentru media RTT-urilor este o estimare pentru abaterea RTT-urilor

faţă de medie (o aproximaţie suficientă pentru abaterea pătratică medie care icircnsă este mult mai

costisitor de calculat) este diferenţa dintre RTT-ul măsurat ( ) şi estimarea curentă ( )

Coeficientul cu care este actualizată estimarea curentă are valoarea de iar cel cu care este

actualizat estimarea abaterii este La stabilirea unei conexiuni valorile pentru şi sunt

alese astfel icircncacirct să rezulte un RTT de secunde şi un de 3 secunde (aceste recomandări

sunt făcute de RFC 1122)

Dacă pentru un anumit segment nu se primeşte confirmarea icircn intervalul indicat de el va fi

retrimis şi noul este dublat Valoarea maximă admisă pentru este de 240 secunde

Deoarece icircn cazul retrimiterilor nu se poate determina cu exactitate căruia din segmentele trimise

aparţine confirmarea actualizarea estimărilor este amacircnată pacircnă cacircnd se reuşeşte trimiterea

corectă (s-a primit confirmare) fără retransmitere(``din prima) a unui segment Acest artificiu

(deloc neimportant) care permite evitarea actualizarea eronată a estimărilor este cunoscut sub

numele de algoritmul lui Karn şi a fost propus icircn 1987 de P Karn şi C Partridge

Evitarea congestiei

Dacă cei doi parteneri care comunică prelucrează datele suficient de repede şi vor să transfere un

volum mare de date atunci limitarea de care se vor lovi este cea dată de viteza reţelei Din cauza

modului ``best-effort pe care IP-ul icircl oferă cacircnd canalul de comunicaţie este saturat o parte din

segmentele TCP se vor pierde Icircn mod poate paradoxal atacirct transmiţătorului cacirct şi receptorul se

pot afla icircn poziţia de a fi primii icircn detectarea pierderii unui segment Unul din indiciile de la

transmiţător care semnalează pierderea unui segment este (icircn mod evident) apariţia 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 icircn varianta iniţială nu

permite decacirct confirmări pozitive singurul lucru pe care receptorul icircl poate face este ca la fiecare

segment out-of-order primit să trimită o confirmare indicacircnd prin aceasta că la el continuă să

vină segmente icircnsă cel indicat de numărul de secvenţă de confirmare lipseşte Primirea acestor

confirmări multiple este al doilea mod icircn care transmiţătorul poate afla de apariţia congestiei

Algoritmul ce trebuie aplicat icircn momentul icircn care se detectează apariţia congestiei este cunoscut

sub numele de ``evitarea congestiei (congestion avoidence) Principiul care stă la baza lui este

ca la apariţia congestiei fie să se treacă la o incrementare liniară a dimensiunii ferestrei dacă

congestia a fost detectată ca urmare a primirii unor confirmări identice repetate fie să se reia

slow start-ul icircn cazul icircn care congestia s-a detectat prin expirarea unui timer de timeout

Implementarea acestui algoritm se bazează pe utilizarea unui nou contor (sstresh) care să indice

dimensiunea ferestrei de la care se trece de la incrementarea exponenţială la cea liniară

Algoritmul efectiv este următorul

1 la stabilirea unei noi conexiuni se pleacă cu sstresh iniţializat la valoare de 64K şi cwnd

la dimensiunea unui segment

2 trimiterea de segmente se face fără a depăşi minimul dintre fereastra publicată de partener

(pentru a nu depăşi capacitatea de procesesare a partenerului) şi cwnd-ul curent (pentru a

nu depăşi limita impusă de capacitatea reţelei)

3 la apariţia congestiei sstresh este setat la jumătatea valorii ferestrei curente (minimul

dintre fereastra anunţată de partener şi cwnd icircnsă cel puţin dimensiunea corespunzătoare

pentru două segmente) dacă congestia a fost detectată prin expirarea unui timer de

timeout atunci cwnd este iniţializat cu dimensiunea unui segment

4 la primirea unei confirmări incrementarea se face icircn două moduri icircn funcţie de relaţie icircn

care se află cwnd şi sstresh

1 dacă cwnd e mai mic sau egal cu sstresh se face incrementarea exponenţială

caracteristică slow start-ului (care de fapt nu e deloc slow icircn cazul de faţă)

2 dacă cwnd e mai mare ca sstresh atunci se face o incrementare cu dimensiunea

unui segment

Fast Retransmission Fast Recovery

După cum am văzut un receptor care primeşte segmente out-of-order va trimite transmiţătorului

confirmări duplicate Algoritmul denumit ``fast retransmission recomandă următoarele două

comportamenet

1 un receptor care detectează segmente out-of order trebuie să nu icircntacircrzie trimiterea de

confirmări (după cum am văzut icircn general confimările sunt icircntacircrziate micşora numărul de

pachete fără date care sunt transferate)

2 un transmiţător care care primeşte mai mult de trei confirmări duplicate trebuie să

retrimită segmentul indicat ca fiind neprimit de confirmările icircn cauză fără a aştepta

expirarea timer-ul de timeout

Algoritmul de ``fast recovery icircncearcă să optimizeze şi mai mult comportamentul

transmiţătorului care detectează un număr de trei sau mai multe confimări duplicate Mai exact el

recomandă trecerea la actualizarea liniară a ferestrei (congestion avoidance) Acest tip de

comportament se poate justifica prin următorul raţionament deoarece icircncă mai sunt transferate

date icircntre cei doi parteneri (şi acest lucru se icircntacircmplă sigur de vreme ce sosesc confirmări

duplicate icircn cazul acesta) icircnseamnă că transferul nu este afectat de o congestie severă şi prin

urmare trecerea la slow start nu e (icircncă) necesară (slow start-ul eliberează aproape complet

canalul deoarece cwnd este resetat la dimensiunea unui singur segment)

Cei doi algoritmi pot fi implementaţi icircn felul următor

1 cacircnd se detectează trei confirmări consecutive identice se setează sstresh la jumătate din

valoarea cwnd se retransmite segmentul care s-a pierdut şi se setează cwnd la valoarea

egală cu sstresh plus dimensiunea a trei segmente (acest lucru va face ca algoritmul de

incrementare a cwnd să treacă la incrementare liniară)

2 la fiecare confirmare duplicată care mai soseşte se incrementează cwnd se incrementează

cu dimensiunea unui segment

3 cacircnd icircncetează primirea de confirmări duplicate (segmentul retrimis a ajuns cu bine la

receptor şi s-a trimis o confirmare care acoperă segmentul care se pierduse iniţial) cwnd

este setat la valoarea sstresh

Sindromul ``Silly Window

Protocoalele bazate pe fereastră glisantă (cum este şi TCP-ul) pot să ajungă icircn situaţia deloc

fericită de trimite un număr mare de segmente mici icircn loc de segmente de dimensiune maximă

Acest tip de comportament este cunoscut sub numele de sindromul ``silly window

O modalitate prin care TCP-ul poate să cadă victimă acestui tip de comportament este

deschiderea de ferestre cu dimensiune foarte mică O altă situaţia nefericită este cea icircn care un

transmiţător este ``lacom şi trimite date indiferent de cacirct de mică este fereastra (după cum vom

vedea imediat uneori are sens şi un astfel de comportament) Algoritmul de evitare a acestor

neajunsuri este următorul

1 un receptor nu trebuie să anunţe deschideri de ferestre mici Mai exact nu se recomandă

anunţarea unei incrementări a ferestrei mai mică decacirct dimensiunea unui segment (MSS)

sau jumătate din buffer-ul aflat la dispoziţia receptorului oricare din ele e mai mică

2 un transmiţător va trimite date doar icircn următoarele cazuri

1 se poate trimite un segment icircntreg

2 se poate trimite jumătate din dimensiunea celei mai mari ferestre pe care

partenerul a publicat-o pacircnă acum

3 toate datele trimise pacircnă acum au fost confirmate sau algoritmul Nagle este

dezactivat şi se trimit toate datele care sunt icircn buffer-ul de trimitere

Cacircteva justificări cazul 2b tratează cazul icircn care partenerul anunţă ferestre mai mici decacirct

dimensiunea unui segment iar cazul 2c impune condiţiile respectării algoritmului Nagle după

cum se vede dacă algoritmul Nagle este activ şi s-au acumulat destul date mai exact cacirct

dimensiunea unui segment el va fi trimis chiar dacă există segmente neconfirmate Pentru

implementarea comportamentului impus de 2b un transmiţător trebuie să ţină evidenţa celei mai

mari ferestre pe care partenerul a anunţat-o Ţinacircnd seama că dimensiunea acestor buffer-e nu se

modifică acest mod de a icircncerca determinarea lor este suficient

O altă problemă legată tot de ferestre este cazul icircnchiderii acesteia Un mod icircn care s-ar putea

anunţa redeschiderea este trimiterea de către receptor a unei confirmări (duplicat) care să anunţe

redeschiderea la o anumită valoare a ferestrei Deoarece acest pachet nu trebuie confirmat icircn mod

special şi s-ar putea să se piardă se poate ajunge icircn situaţia icircn care receptorul a anunţat

redeschiderea ferestrei segmentul s-a pierdut iar transmiţătorul icircncă mai icircl mai aşteaptă pentru a

putea continua transferul Rezolvarea la această problemă s-a făcut prin impunerea unui alt

comportament

1 transmiţătorul va trimite segmente cu dimensiunea datelor de un octet prin care sondează

deschiderea ferestrei intervalul la care se sondează redeschiderea ferestrei se dublează

(exponenţial backoff) icircn RFC 793 dimensiunea maximă recomandată este de 2 minute

icircnsă icircn RFC 1122 se specifică că maximul este acelaşi cu cel din cazul retransmisiei (240

secunde)

2 receptorul trebuie să refuze aceste pachete răspunzacircnd cu segmente de confirmare care

indică neprimirea octetului respectiv

Observaţie timer-ul special necesar pentru implementare la transmiţător a comportamentului de mai sus este cunoscut sub numele de ``TCP Persistent Timer Numele este justificat de faptul că sondarea deschiderii se va face pacircnă cacircnd fie fereastra se deschide fie conexiunea se icircntrerupe TCP Keepalive Timer

Un lucru interesant despre TCP este faptul că dacă nivelele superioare nu comunică nimic icircntre

ele pentru o perioadă lungă 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 icircn care au trecut cu succes de faza stabilirii legăturii Dacă nivelurile

inferioare (reţeaIP fizic) devin temporar indisponibile cacirct tip cei doi nu vor să comunice atunci

acest lucru nu va perturba icircn nici un fel activitatea şi acest lucru este acceptabil Problemele

icircncep să apară icircn momentul icircn care cei doi doresc să comunice şi nivelele inferioare nu mai

permit acest lucru Evident că cel care va dori să comunice ceva va detecta icircntreruperea legăturii

şi va icircnchide conexiunea Ce se icircntacircmplă icircnsă dacă celălalt capăt nu are nimic de comunicat (de

exemplu este un server care oferă anumite servicii) Pentru el legătura va fi icircn continuare activă

şi icircn general anumite resurse vor fi rezervate pentru aceasta Rezolvarea acestei situaţii este dată

de introducerea unei mecanism de sondare a stării legăturii pe baza unui timer (TCP Keepalive

Timer) care se declanşează din două icircn două ore La fiecare expirare a timer-ului se trimite un

segment fără date care confirmă datele primite pacircnă atunci Răspunsul care trebuie primit este tot

un segment fără date care confirmă datele primite de partener (practic o re-publicare a stării celor

doi parteneri) Dacă răspunsul nu este primit timp de 75 secunde atunci segmentul va fi retrimis

Dacă după 10 astfel de icircncercări tot nu s-a primit nici un răspuns atunci conexiunea se va

considera terminată şi se va anunţa nivelul superior asupra acestui lucru

Observaţii

dacă o staţie primeşte segmente de keepalive despre conexiuni care nu mai sunt active

(de exemplu a fost resetat) atunci va răspunde cu segmente de reset (acesta e un procedeu

standard)

RFC 1122 specifică că facilitatea de keepalive trebuie activată icircn mod explicit

3 Studii de caz

Subsections

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

1 Fragmentarea pachetelor UDP

Deoarece UDP-ul este un serviciu fără conexiune toate datele pe care le primeşte de la nivelul

superior sunt icircncapsulate icircntr-o singură datagramă UDP care apoi va forma un pachet IP Dacă

pachetul IP astfel obţinut este prea mare atunci mecanismele IP de fragmentare icircl vor sparge icircn

bucăţi Exemplul următor icircncearcă să studieze exact acest fenomen

Pe maşina athos rulează un server de UDP pe portul 50007 Pe o altă maşină frodo aflată icircn

reţeaua locală este rulat un client care poate fi configurat să trimită un pachet UDP de o anumită

lungime Pentru a putea observa ce se icircntacircmplă pe athos este rulat tcpdump

Deoarece MTU-ul pentru o reţea Ethernet este icircn general 1500 şi antetul IP plus cel UDP ocupă

20 + 8 = 28 octeţi o datagramă UDP de dimensiune 1472 ar trebui sa fie trimisă nefragmentată

Pentru siguranţă folosind clientul de pe athos s-a trimis mai icircntacirci o datagramă UDP cu 1471

octeţi de date şi apoi icircncă una cu 1472 Pentru ambele tcpdump a indicat trimiterea lor fără

fragmentare

182556721144 frodonoi33274 gt athosnoi50007 udp 1471 (DF) (ttl 64 id

51481 len 1499)

182559846764 frodonoi33274 gt athosnoi50007 udp 1472 (DF) (ttl 64 id

51793 len 1500)

La o dimensiune de 1473 ar trebui ca trimiterea să genereze două pachete IP unul care să

conţină primii antetul UDP plus primii 1472 octeţi de date şi icircncă un pachet IP care conţine un

singur octet Iată ce indică tcpdump-ul

182605705813 frodonoi gt athosnoi udp (frag 3627411480) (ttl 64 len

21)

182605706116 frodonoi33274 gt athosnoi50007 udp 1473 (frag

3627414800+) (ttl 64 len 1500)

Intr-adevăr au fost generate două pachete IP

primul conţine doar un singur octet de date şi reprezintă ultimul fragment (bitul de more

fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest

lucru) care a fost spartă icircn bucăţi deplasamentul octetului primit in datagrama originală

este 1480

al doilea pachet este primul fragment din datagrama UDP şi conţine antetul UDP (din

cauza asta datele efective ocupă doar 1480 octeţi) deplasamentul este 0 şi bitul de more

fragments este setat (acest lucru este indicat de semnul ``+ de după deplasament)

După cum se poate observa ambele pachete poartă acelaşi număr de identificare (36274) Acest

lucru icircmpreună cu informaţiile date de flag-ul more fragments permite reconstrucţia la

destinaţie a datagramei UDP originale O problemă a acestui mod de fragmentare e că icircn cazul

pierderii unui fragment icircntreaga datagramă va fi compromisă şi va trebui retrimisă icircn icircntregime

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 14: udp tcp

4 Controlul fluxului

Dacă icircncă de la icircnceput s-a reuşit stabilirea formatului unui pachet TCP şi a modulului icircn care

trebuie să se facă icircnchiderea şi deschiderea unei conexiuni nu acelaşi lucru se poate spune şi

despre modul icircn care ar trebui să se realizeze controlul fluxului Ţinacircnd seama icircnsă că din 1989

(de cacircnd datează RFC-ul 2581 cel despre care am menţionat că specifică icircn mod clar modul icircn

care trebuie să se comporte o implementare de TCP) TCP-ul a rămas neschimbat putem să icircl

considerăm un rezultat important al domeniului reţelor de calculatoare

Icircn cele ce urmează vom icircnţelege prin controlul fluxului totalitatea algoritmilor care permit

atingerea unei viteze de transfer punct-la-punct cacirct mai mare pentru toate conexiunile existente

Icircn principal aceşti algoritmi stabilesc modul icircn care segmentele şi confirmările trebuie trimise şi

ce acţiuni trebuie executate icircn situaţiile icircn care răspunsurile aşteptate de la celălalt capăt icircntacircrzie

să vină

Subsections

Icircntacircrzierea confirmărilor

Algoritmul Nagle

Fereastra glisantă

Slow start

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Evitarea congestiei

Fast Retransmission Fast Recovery

Sindromul ``Silly Window

TCP Keepalive Timer

Icircntacircrzierea confirmărilor

O modalitate simplă de generare a confirmărilor este de a trimite cacircte una pentru fiecare segment

primit Această politică prezintă avantajul de a face comunicaţia self-clocking icircnsă este

ineficientă dacă segmentele care nu conţin decacirct confirmări sunt urmate la scurtă distanţă (cacircteva

zeci de milisecunde) de segmente ce conţin date efective Pentru a evita această situaţie se

procedează2 la icircntacircrzierea (200ms este o valoare uzuală icircn RFC 1122 se specifică o valoare

maximă de 500ms) a segmentelor care conţin doar confirmări Această strategie face posibil ca

un răspuns generat de primirea unor date să plece sper celălalt capăt icircn acelaşi segment cu

confirmarea

Observaţie deoarece este dificil de menţinut timere pentru fiecare confirmare diferenţa de

200ms este calculată de un timer global Din acest motiv modul efectiv de comportare poate fi

descris şi icircn felul următor cacircnd un segment nu conţine decacirct o confirmare el este pus icircntr-o

coadă ce va fi inspectată de un proces care din 200 icircn 200 ms trimite tot ce s-a acumulat icircn

coada

Footnotes

2

Acest comportament a fost propus de David D Clark icircn iulie 1982 icircn RFC 813

Algoritmul Nagle

Acest algoritm3 icircncearcă să icircmbunătăţească performanţele exploatacircnd următoarea caracteristică

foarte des icircntacirclnită icircn dialogul dintre două staţii dacă se icircncearcă trimiterea unor date de

dimensiune mică icircnsă există icircncă date neconfirmate de partener atunci ele sunt buffer-ate şi

trimise icircntr-un segment mai mare cacircnd soseşte confirmarea aşteptată Icircn acest fel se poate evita

generarea datagramelor mici (tinygrame) icircn situaţia unei legături lente Icircn cazul unei legături

rapide confirmările vor veni repede şi icircntacircrzierea introdusă de algoritm va neglijabilă

Există icircnsă şi cazuri icircn care acest algoritm duce la deprecierea performanţelor mesajele scurte

generate de mişcările mouse-ului icircn cazul folosirii unui server X Window sau utilizarea tastelor

care trimit mai mult de un caracter (secvenţe escape) Pentru a rezolva aceste inconveninte API-

ul de utilizare a TCP-ului trebuie să ofere o modalitate de a dezactiva acest algoritm (icircn sistemele

bazate pe sockeţi există icircn acest scop opţiunea TCP_NODELAY)

Footnotes

algoritm3

Algoritmul aparţinacircnd lui John Nagle a fost propus icircn ianuarie 1984 icircn RFC 896

Fereastra glisantă

Algoritmul implementat de TCP pentru a implementa transferul sigur de date este cunoscut icircn

teorie sub numele de Go-Back-N Icircn acest algoritm se utilizează numere de secvenţă pentru a

distinge pachetele icircntre ele şi o coadă (dimensiunea maximă a cozii reprezintă fereastra) de

pachetele a căror confirmare se aşteaptă Pachetele se icircmpart icircn 4 categorii

1 pachete trimis şi pentru care s-a primit confirmare

2 pachete trimise şi pentru care se aşteaptă icircncă confirmarea

3 pachete care nu au fost trimise icircncă dar care nu depăşesc limitele ferestrei şi deci pot fi

trimise

4 pachete care icircncă nu au fost trimite şi care nici nu vor putea fi trimise decacirct după ce au

fost trimise toate pachetele din categoria 3 şi s-au primit o parte din confirmările la

pachetele din categoria 2

Dacă confirmările pentru pachetele din categoria 2 icircntacircrzie prea mult (un mecanism de timer-e

informează asupra acestui lucru) atunci ele vor fi retrimise Icircn versiunea iniţială TCP-ul nu

permitea decacirct confirmări pozitive ceea ce icircnseamnă că avansarea ferestrei se va icircmpotmoli la

segmentele neconfirmate Cum se poate evita aceasta situaţie vom discuta icircn detaliu icircn capitolele

următoare O soluţie foarte radicală o constituie introducerea de confirmări selective (acest lucru

este realizat de RFC 2018 din octombrie 1996) Această modifică face ca TCP-ul actual să fie un

hibrid de Go-Back-N şi Selective Repeat

Deoarece dimensiunea ferestrei este anunţată la fiecare segment un client lent poate ca pe măsură

ce trimite confirmările să informeze despre progresul icircnregistrat la livrarea datelor următorului

nivel (aplicaţie) Dacă datele vin prea repede pentru viteza cu care clientul procesează datele

fereastra fereastra se va dimiua şi chiar icircnchide (acest lucru se realizează anunţacircnd o fereastră de

dimensiune zero) Cum se realizează efectiv redeschiderea vom analiza icircntr-un capitol viitor

Slow start

Un transfer de date TCP poate să icircnceapă prin transmiterea de segmente pacircnă la umplerea

icircntregii ferestre după care fie se primesc confirmări care vor permite unor noi pachete să fie

trimise fie vor expira timer-ele de retransmisie şi se va icircncepe retrimiterea pachetelor de la

icircnceputul ferestrei Din păcate un astfel de comportament poate duce la pomparea icircn reţea a unui

număr de pachete prea mare pentru capacitatea disponibilă efectiv icircnrăutăţind congestia Pentru

a evita acest lucru s-a propus următoarea soluţie4 iniţial se trimite un segment după primirea

confirmării lui se trimit două segmente după sosirea confirmărilor pentru ele se trimit patru

segmente şi aşa mai departe La un moment dat fie vor icircncepe să se piardă segmente (un indiciu

că s-a atins capacitatea maximă a canalului) fie se va umple fereastra pe care o anunţă cel care

primeşte Trebuie să remarcam că datorită creşterii exponenţiale a numărului de segmente se va

atinge destul de repede una din cele două situaţii

Modalitatea efectivă de implementare a acestui algoritm are la bază utilizarea unei ferestre de

congestie (congestion window cwnd) care este iniţializată cu dimensiunea unui segment (cwnd

se calculează icircn octeţi) şi la fiecare pas este dublată fereastra efectivă din cadrul căreia se pot

trimite segmente este dată de minimul dintre ultima fereastra comunicată de partener şi cwnd

Footnotes

soluţie4

Soluţia aparţine lui V Jacobson şi a fost prezentată icircn 1988 la conferinţă ACM

SIGCOMM-88

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Deoarece TCP trebuie să funcţioneze icircn condiţii variate de latenţă modul icircn care se face

retransmiterea trebuie să fie cacirct mai flexibil (şi simplu icircn acelaşi timp pentru a introduce un

overhead cacirct mai mic) Timpul cacirct se aşteaptă venirea unei confirmări (retransmission timeout

RTO) este calculat prin cronometrarea timpului care icirci ia unui segment trimis să fie confirmat

Pentru o anumită conexiune se cronometrează cacircte un singur segment la un moment dat iar pe

baza RTT-ului măsurat se actualizează valoare RTO-ului

Icircn RFC 793 formula de calcul a RTO-ului este următoarea

unde este ultimul RTT măsurat este o estimare ponderată pentru RTT este un coeficient

de ponderare care icircn general are valoarea iar este un coeficient cu o valoare recomandată

de După cum se poate observa icircn valoarea lui este inclusă icircn mare măsură vechea valoarea

Icircn acest fel ajustarea RTT-ului se face treptat Din păcate acest mod de calcul nu funcţionează

bine la variaţii mari ale RTT-ului ducacircnd la creşterea numărului de retransmisii exact atunci

cacircnd fenomenul de congestie icircncepe să apară

Pentru a remedia aceste neajunsuri V Jacobsen a propus icircn 1988 o nouă metodă de calcul o

metodă care ţine seama seamă şi de modul icircn care variază diferenţa dintre RTT-uri Formulele

folosite sunt următoarele

unde este un estimare pentru media RTT-urilor este o estimare pentru abaterea RTT-urilor

faţă de medie (o aproximaţie suficientă pentru abaterea pătratică medie care icircnsă este mult mai

costisitor de calculat) este diferenţa dintre RTT-ul măsurat ( ) şi estimarea curentă ( )

Coeficientul cu care este actualizată estimarea curentă are valoarea de iar cel cu care este

actualizat estimarea abaterii este La stabilirea unei conexiuni valorile pentru şi sunt

alese astfel icircncacirct să rezulte un RTT de secunde şi un de 3 secunde (aceste recomandări

sunt făcute de RFC 1122)

Dacă pentru un anumit segment nu se primeşte confirmarea icircn intervalul indicat de el va fi

retrimis şi noul este dublat Valoarea maximă admisă pentru este de 240 secunde

Deoarece icircn cazul retrimiterilor nu se poate determina cu exactitate căruia din segmentele trimise

aparţine confirmarea actualizarea estimărilor este amacircnată pacircnă cacircnd se reuşeşte trimiterea

corectă (s-a primit confirmare) fără retransmitere(``din prima) a unui segment Acest artificiu

(deloc neimportant) care permite evitarea actualizarea eronată a estimărilor este cunoscut sub

numele de algoritmul lui Karn şi a fost propus icircn 1987 de P Karn şi C Partridge

Evitarea congestiei

Dacă cei doi parteneri care comunică prelucrează datele suficient de repede şi vor să transfere un

volum mare de date atunci limitarea de care se vor lovi este cea dată de viteza reţelei Din cauza

modului ``best-effort pe care IP-ul icircl oferă cacircnd canalul de comunicaţie este saturat o parte din

segmentele TCP se vor pierde Icircn mod poate paradoxal atacirct transmiţătorului cacirct şi receptorul se

pot afla icircn poziţia de a fi primii icircn detectarea pierderii unui segment Unul din indiciile de la

transmiţător care semnalează pierderea unui segment este (icircn mod evident) apariţia 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 icircn varianta iniţială nu

permite decacirct confirmări pozitive singurul lucru pe care receptorul icircl poate face este ca la fiecare

segment out-of-order primit să trimită o confirmare indicacircnd prin aceasta că la el continuă să

vină segmente icircnsă cel indicat de numărul de secvenţă de confirmare lipseşte Primirea acestor

confirmări multiple este al doilea mod icircn care transmiţătorul poate afla de apariţia congestiei

Algoritmul ce trebuie aplicat icircn momentul icircn care se detectează apariţia congestiei este cunoscut

sub numele de ``evitarea congestiei (congestion avoidence) Principiul care stă la baza lui este

ca la apariţia congestiei fie să se treacă la o incrementare liniară a dimensiunii ferestrei dacă

congestia a fost detectată ca urmare a primirii unor confirmări identice repetate fie să se reia

slow start-ul icircn cazul icircn care congestia s-a detectat prin expirarea unui timer de timeout

Implementarea acestui algoritm se bazează pe utilizarea unui nou contor (sstresh) care să indice

dimensiunea ferestrei de la care se trece de la incrementarea exponenţială la cea liniară

Algoritmul efectiv este următorul

1 la stabilirea unei noi conexiuni se pleacă cu sstresh iniţializat la valoare de 64K şi cwnd

la dimensiunea unui segment

2 trimiterea de segmente se face fără a depăşi minimul dintre fereastra publicată de partener

(pentru a nu depăşi capacitatea de procesesare a partenerului) şi cwnd-ul curent (pentru a

nu depăşi limita impusă de capacitatea reţelei)

3 la apariţia congestiei sstresh este setat la jumătatea valorii ferestrei curente (minimul

dintre fereastra anunţată de partener şi cwnd icircnsă cel puţin dimensiunea corespunzătoare

pentru două segmente) dacă congestia a fost detectată prin expirarea unui timer de

timeout atunci cwnd este iniţializat cu dimensiunea unui segment

4 la primirea unei confirmări incrementarea se face icircn două moduri icircn funcţie de relaţie icircn

care se află cwnd şi sstresh

1 dacă cwnd e mai mic sau egal cu sstresh se face incrementarea exponenţială

caracteristică slow start-ului (care de fapt nu e deloc slow icircn cazul de faţă)

2 dacă cwnd e mai mare ca sstresh atunci se face o incrementare cu dimensiunea

unui segment

Fast Retransmission Fast Recovery

După cum am văzut un receptor care primeşte segmente out-of-order va trimite transmiţătorului

confirmări duplicate Algoritmul denumit ``fast retransmission recomandă următoarele două

comportamenet

1 un receptor care detectează segmente out-of order trebuie să nu icircntacircrzie trimiterea de

confirmări (după cum am văzut icircn general confimările sunt icircntacircrziate micşora numărul de

pachete fără date care sunt transferate)

2 un transmiţător care care primeşte mai mult de trei confirmări duplicate trebuie să

retrimită segmentul indicat ca fiind neprimit de confirmările icircn cauză fără a aştepta

expirarea timer-ul de timeout

Algoritmul de ``fast recovery icircncearcă să optimizeze şi mai mult comportamentul

transmiţătorului care detectează un număr de trei sau mai multe confimări duplicate Mai exact el

recomandă trecerea la actualizarea liniară a ferestrei (congestion avoidance) Acest tip de

comportament se poate justifica prin următorul raţionament deoarece icircncă mai sunt transferate

date icircntre cei doi parteneri (şi acest lucru se icircntacircmplă sigur de vreme ce sosesc confirmări

duplicate icircn cazul acesta) icircnseamnă că transferul nu este afectat de o congestie severă şi prin

urmare trecerea la slow start nu e (icircncă) necesară (slow start-ul eliberează aproape complet

canalul deoarece cwnd este resetat la dimensiunea unui singur segment)

Cei doi algoritmi pot fi implementaţi icircn felul următor

1 cacircnd se detectează trei confirmări consecutive identice se setează sstresh la jumătate din

valoarea cwnd se retransmite segmentul care s-a pierdut şi se setează cwnd la valoarea

egală cu sstresh plus dimensiunea a trei segmente (acest lucru va face ca algoritmul de

incrementare a cwnd să treacă la incrementare liniară)

2 la fiecare confirmare duplicată care mai soseşte se incrementează cwnd se incrementează

cu dimensiunea unui segment

3 cacircnd icircncetează primirea de confirmări duplicate (segmentul retrimis a ajuns cu bine la

receptor şi s-a trimis o confirmare care acoperă segmentul care se pierduse iniţial) cwnd

este setat la valoarea sstresh

Sindromul ``Silly Window

Protocoalele bazate pe fereastră glisantă (cum este şi TCP-ul) pot să ajungă icircn situaţia deloc

fericită de trimite un număr mare de segmente mici icircn loc de segmente de dimensiune maximă

Acest tip de comportament este cunoscut sub numele de sindromul ``silly window

O modalitate prin care TCP-ul poate să cadă victimă acestui tip de comportament este

deschiderea de ferestre cu dimensiune foarte mică O altă situaţia nefericită este cea icircn care un

transmiţător este ``lacom şi trimite date indiferent de cacirct de mică este fereastra (după cum vom

vedea imediat uneori are sens şi un astfel de comportament) Algoritmul de evitare a acestor

neajunsuri este următorul

1 un receptor nu trebuie să anunţe deschideri de ferestre mici Mai exact nu se recomandă

anunţarea unei incrementări a ferestrei mai mică decacirct dimensiunea unui segment (MSS)

sau jumătate din buffer-ul aflat la dispoziţia receptorului oricare din ele e mai mică

2 un transmiţător va trimite date doar icircn următoarele cazuri

1 se poate trimite un segment icircntreg

2 se poate trimite jumătate din dimensiunea celei mai mari ferestre pe care

partenerul a publicat-o pacircnă acum

3 toate datele trimise pacircnă acum au fost confirmate sau algoritmul Nagle este

dezactivat şi se trimit toate datele care sunt icircn buffer-ul de trimitere

Cacircteva justificări cazul 2b tratează cazul icircn care partenerul anunţă ferestre mai mici decacirct

dimensiunea unui segment iar cazul 2c impune condiţiile respectării algoritmului Nagle după

cum se vede dacă algoritmul Nagle este activ şi s-au acumulat destul date mai exact cacirct

dimensiunea unui segment el va fi trimis chiar dacă există segmente neconfirmate Pentru

implementarea comportamentului impus de 2b un transmiţător trebuie să ţină evidenţa celei mai

mari ferestre pe care partenerul a anunţat-o Ţinacircnd seama că dimensiunea acestor buffer-e nu se

modifică acest mod de a icircncerca determinarea lor este suficient

O altă problemă legată tot de ferestre este cazul icircnchiderii acesteia Un mod icircn care s-ar putea

anunţa redeschiderea este trimiterea de către receptor a unei confirmări (duplicat) care să anunţe

redeschiderea la o anumită valoare a ferestrei Deoarece acest pachet nu trebuie confirmat icircn mod

special şi s-ar putea să se piardă se poate ajunge icircn situaţia icircn care receptorul a anunţat

redeschiderea ferestrei segmentul s-a pierdut iar transmiţătorul icircncă mai icircl mai aşteaptă pentru a

putea continua transferul Rezolvarea la această problemă s-a făcut prin impunerea unui alt

comportament

1 transmiţătorul va trimite segmente cu dimensiunea datelor de un octet prin care sondează

deschiderea ferestrei intervalul la care se sondează redeschiderea ferestrei se dublează

(exponenţial backoff) icircn RFC 793 dimensiunea maximă recomandată este de 2 minute

icircnsă icircn RFC 1122 se specifică că maximul este acelaşi cu cel din cazul retransmisiei (240

secunde)

2 receptorul trebuie să refuze aceste pachete răspunzacircnd cu segmente de confirmare care

indică neprimirea octetului respectiv

Observaţie timer-ul special necesar pentru implementare la transmiţător a comportamentului de mai sus este cunoscut sub numele de ``TCP Persistent Timer Numele este justificat de faptul că sondarea deschiderii se va face pacircnă cacircnd fie fereastra se deschide fie conexiunea se icircntrerupe TCP Keepalive Timer

Un lucru interesant despre TCP este faptul că dacă nivelele superioare nu comunică nimic icircntre

ele pentru o perioadă lungă 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 icircn care au trecut cu succes de faza stabilirii legăturii Dacă nivelurile

inferioare (reţeaIP fizic) devin temporar indisponibile cacirct tip cei doi nu vor să comunice atunci

acest lucru nu va perturba icircn nici un fel activitatea şi acest lucru este acceptabil Problemele

icircncep să apară icircn momentul icircn care cei doi doresc să comunice şi nivelele inferioare nu mai

permit acest lucru Evident că cel care va dori să comunice ceva va detecta icircntreruperea legăturii

şi va icircnchide conexiunea Ce se icircntacircmplă icircnsă dacă celălalt capăt nu are nimic de comunicat (de

exemplu este un server care oferă anumite servicii) Pentru el legătura va fi icircn continuare activă

şi icircn general anumite resurse vor fi rezervate pentru aceasta Rezolvarea acestei situaţii este dată

de introducerea unei mecanism de sondare a stării legăturii pe baza unui timer (TCP Keepalive

Timer) care se declanşează din două icircn două ore La fiecare expirare a timer-ului se trimite un

segment fără date care confirmă datele primite pacircnă atunci Răspunsul care trebuie primit este tot

un segment fără date care confirmă datele primite de partener (practic o re-publicare a stării celor

doi parteneri) Dacă răspunsul nu este primit timp de 75 secunde atunci segmentul va fi retrimis

Dacă după 10 astfel de icircncercări tot nu s-a primit nici un răspuns atunci conexiunea se va

considera terminată şi se va anunţa nivelul superior asupra acestui lucru

Observaţii

dacă o staţie primeşte segmente de keepalive despre conexiuni care nu mai sunt active

(de exemplu a fost resetat) atunci va răspunde cu segmente de reset (acesta e un procedeu

standard)

RFC 1122 specifică că facilitatea de keepalive trebuie activată icircn mod explicit

3 Studii de caz

Subsections

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

1 Fragmentarea pachetelor UDP

Deoarece UDP-ul este un serviciu fără conexiune toate datele pe care le primeşte de la nivelul

superior sunt icircncapsulate icircntr-o singură datagramă UDP care apoi va forma un pachet IP Dacă

pachetul IP astfel obţinut este prea mare atunci mecanismele IP de fragmentare icircl vor sparge icircn

bucăţi Exemplul următor icircncearcă să studieze exact acest fenomen

Pe maşina athos rulează un server de UDP pe portul 50007 Pe o altă maşină frodo aflată icircn

reţeaua locală este rulat un client care poate fi configurat să trimită un pachet UDP de o anumită

lungime Pentru a putea observa ce se icircntacircmplă pe athos este rulat tcpdump

Deoarece MTU-ul pentru o reţea Ethernet este icircn general 1500 şi antetul IP plus cel UDP ocupă

20 + 8 = 28 octeţi o datagramă UDP de dimensiune 1472 ar trebui sa fie trimisă nefragmentată

Pentru siguranţă folosind clientul de pe athos s-a trimis mai icircntacirci o datagramă UDP cu 1471

octeţi de date şi apoi icircncă una cu 1472 Pentru ambele tcpdump a indicat trimiterea lor fără

fragmentare

182556721144 frodonoi33274 gt athosnoi50007 udp 1471 (DF) (ttl 64 id

51481 len 1499)

182559846764 frodonoi33274 gt athosnoi50007 udp 1472 (DF) (ttl 64 id

51793 len 1500)

La o dimensiune de 1473 ar trebui ca trimiterea să genereze două pachete IP unul care să

conţină primii antetul UDP plus primii 1472 octeţi de date şi icircncă un pachet IP care conţine un

singur octet Iată ce indică tcpdump-ul

182605705813 frodonoi gt athosnoi udp (frag 3627411480) (ttl 64 len

21)

182605706116 frodonoi33274 gt athosnoi50007 udp 1473 (frag

3627414800+) (ttl 64 len 1500)

Intr-adevăr au fost generate două pachete IP

primul conţine doar un singur octet de date şi reprezintă ultimul fragment (bitul de more

fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest

lucru) care a fost spartă icircn bucăţi deplasamentul octetului primit in datagrama originală

este 1480

al doilea pachet este primul fragment din datagrama UDP şi conţine antetul UDP (din

cauza asta datele efective ocupă doar 1480 octeţi) deplasamentul este 0 şi bitul de more

fragments este setat (acest lucru este indicat de semnul ``+ de după deplasament)

După cum se poate observa ambele pachete poartă acelaşi număr de identificare (36274) Acest

lucru icircmpreună cu informaţiile date de flag-ul more fragments permite reconstrucţia la

destinaţie a datagramei UDP originale O problemă a acestui mod de fragmentare e că icircn cazul

pierderii unui fragment icircntreaga datagramă va fi compromisă şi va trebui retrimisă icircn icircntregime

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 15: udp tcp

Footnotes

2

Acest comportament a fost propus de David D Clark icircn iulie 1982 icircn RFC 813

Algoritmul Nagle

Acest algoritm3 icircncearcă să icircmbunătăţească performanţele exploatacircnd următoarea caracteristică

foarte des icircntacirclnită icircn dialogul dintre două staţii dacă se icircncearcă trimiterea unor date de

dimensiune mică icircnsă există icircncă date neconfirmate de partener atunci ele sunt buffer-ate şi

trimise icircntr-un segment mai mare cacircnd soseşte confirmarea aşteptată Icircn acest fel se poate evita

generarea datagramelor mici (tinygrame) icircn situaţia unei legături lente Icircn cazul unei legături

rapide confirmările vor veni repede şi icircntacircrzierea introdusă de algoritm va neglijabilă

Există icircnsă şi cazuri icircn care acest algoritm duce la deprecierea performanţelor mesajele scurte

generate de mişcările mouse-ului icircn cazul folosirii unui server X Window sau utilizarea tastelor

care trimit mai mult de un caracter (secvenţe escape) Pentru a rezolva aceste inconveninte API-

ul de utilizare a TCP-ului trebuie să ofere o modalitate de a dezactiva acest algoritm (icircn sistemele

bazate pe sockeţi există icircn acest scop opţiunea TCP_NODELAY)

Footnotes

algoritm3

Algoritmul aparţinacircnd lui John Nagle a fost propus icircn ianuarie 1984 icircn RFC 896

Fereastra glisantă

Algoritmul implementat de TCP pentru a implementa transferul sigur de date este cunoscut icircn

teorie sub numele de Go-Back-N Icircn acest algoritm se utilizează numere de secvenţă pentru a

distinge pachetele icircntre ele şi o coadă (dimensiunea maximă a cozii reprezintă fereastra) de

pachetele a căror confirmare se aşteaptă Pachetele se icircmpart icircn 4 categorii

1 pachete trimis şi pentru care s-a primit confirmare

2 pachete trimise şi pentru care se aşteaptă icircncă confirmarea

3 pachete care nu au fost trimise icircncă dar care nu depăşesc limitele ferestrei şi deci pot fi

trimise

4 pachete care icircncă nu au fost trimite şi care nici nu vor putea fi trimise decacirct după ce au

fost trimise toate pachetele din categoria 3 şi s-au primit o parte din confirmările la

pachetele din categoria 2

Dacă confirmările pentru pachetele din categoria 2 icircntacircrzie prea mult (un mecanism de timer-e

informează asupra acestui lucru) atunci ele vor fi retrimise Icircn versiunea iniţială TCP-ul nu

permitea decacirct confirmări pozitive ceea ce icircnseamnă că avansarea ferestrei se va icircmpotmoli la

segmentele neconfirmate Cum se poate evita aceasta situaţie vom discuta icircn detaliu icircn capitolele

următoare O soluţie foarte radicală o constituie introducerea de confirmări selective (acest lucru

este realizat de RFC 2018 din octombrie 1996) Această modifică face ca TCP-ul actual să fie un

hibrid de Go-Back-N şi Selective Repeat

Deoarece dimensiunea ferestrei este anunţată la fiecare segment un client lent poate ca pe măsură

ce trimite confirmările să informeze despre progresul icircnregistrat la livrarea datelor următorului

nivel (aplicaţie) Dacă datele vin prea repede pentru viteza cu care clientul procesează datele

fereastra fereastra se va dimiua şi chiar icircnchide (acest lucru se realizează anunţacircnd o fereastră de

dimensiune zero) Cum se realizează efectiv redeschiderea vom analiza icircntr-un capitol viitor

Slow start

Un transfer de date TCP poate să icircnceapă prin transmiterea de segmente pacircnă la umplerea

icircntregii ferestre după care fie se primesc confirmări care vor permite unor noi pachete să fie

trimise fie vor expira timer-ele de retransmisie şi se va icircncepe retrimiterea pachetelor de la

icircnceputul ferestrei Din păcate un astfel de comportament poate duce la pomparea icircn reţea a unui

număr de pachete prea mare pentru capacitatea disponibilă efectiv icircnrăutăţind congestia Pentru

a evita acest lucru s-a propus următoarea soluţie4 iniţial se trimite un segment după primirea

confirmării lui se trimit două segmente după sosirea confirmărilor pentru ele se trimit patru

segmente şi aşa mai departe La un moment dat fie vor icircncepe să se piardă segmente (un indiciu

că s-a atins capacitatea maximă a canalului) fie se va umple fereastra pe care o anunţă cel care

primeşte Trebuie să remarcam că datorită creşterii exponenţiale a numărului de segmente se va

atinge destul de repede una din cele două situaţii

Modalitatea efectivă de implementare a acestui algoritm are la bază utilizarea unei ferestre de

congestie (congestion window cwnd) care este iniţializată cu dimensiunea unui segment (cwnd

se calculează icircn octeţi) şi la fiecare pas este dublată fereastra efectivă din cadrul căreia se pot

trimite segmente este dată de minimul dintre ultima fereastra comunicată de partener şi cwnd

Footnotes

soluţie4

Soluţia aparţine lui V Jacobson şi a fost prezentată icircn 1988 la conferinţă ACM

SIGCOMM-88

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Deoarece TCP trebuie să funcţioneze icircn condiţii variate de latenţă modul icircn care se face

retransmiterea trebuie să fie cacirct mai flexibil (şi simplu icircn acelaşi timp pentru a introduce un

overhead cacirct mai mic) Timpul cacirct se aşteaptă venirea unei confirmări (retransmission timeout

RTO) este calculat prin cronometrarea timpului care icirci ia unui segment trimis să fie confirmat

Pentru o anumită conexiune se cronometrează cacircte un singur segment la un moment dat iar pe

baza RTT-ului măsurat se actualizează valoare RTO-ului

Icircn RFC 793 formula de calcul a RTO-ului este următoarea

unde este ultimul RTT măsurat este o estimare ponderată pentru RTT este un coeficient

de ponderare care icircn general are valoarea iar este un coeficient cu o valoare recomandată

de După cum se poate observa icircn valoarea lui este inclusă icircn mare măsură vechea valoarea

Icircn acest fel ajustarea RTT-ului se face treptat Din păcate acest mod de calcul nu funcţionează

bine la variaţii mari ale RTT-ului ducacircnd la creşterea numărului de retransmisii exact atunci

cacircnd fenomenul de congestie icircncepe să apară

Pentru a remedia aceste neajunsuri V Jacobsen a propus icircn 1988 o nouă metodă de calcul o

metodă care ţine seama seamă şi de modul icircn care variază diferenţa dintre RTT-uri Formulele

folosite sunt următoarele

unde este un estimare pentru media RTT-urilor este o estimare pentru abaterea RTT-urilor

faţă de medie (o aproximaţie suficientă pentru abaterea pătratică medie care icircnsă este mult mai

costisitor de calculat) este diferenţa dintre RTT-ul măsurat ( ) şi estimarea curentă ( )

Coeficientul cu care este actualizată estimarea curentă are valoarea de iar cel cu care este

actualizat estimarea abaterii este La stabilirea unei conexiuni valorile pentru şi sunt

alese astfel icircncacirct să rezulte un RTT de secunde şi un de 3 secunde (aceste recomandări

sunt făcute de RFC 1122)

Dacă pentru un anumit segment nu se primeşte confirmarea icircn intervalul indicat de el va fi

retrimis şi noul este dublat Valoarea maximă admisă pentru este de 240 secunde

Deoarece icircn cazul retrimiterilor nu se poate determina cu exactitate căruia din segmentele trimise

aparţine confirmarea actualizarea estimărilor este amacircnată pacircnă cacircnd se reuşeşte trimiterea

corectă (s-a primit confirmare) fără retransmitere(``din prima) a unui segment Acest artificiu

(deloc neimportant) care permite evitarea actualizarea eronată a estimărilor este cunoscut sub

numele de algoritmul lui Karn şi a fost propus icircn 1987 de P Karn şi C Partridge

Evitarea congestiei

Dacă cei doi parteneri care comunică prelucrează datele suficient de repede şi vor să transfere un

volum mare de date atunci limitarea de care se vor lovi este cea dată de viteza reţelei Din cauza

modului ``best-effort pe care IP-ul icircl oferă cacircnd canalul de comunicaţie este saturat o parte din

segmentele TCP se vor pierde Icircn mod poate paradoxal atacirct transmiţătorului cacirct şi receptorul se

pot afla icircn poziţia de a fi primii icircn detectarea pierderii unui segment Unul din indiciile de la

transmiţător care semnalează pierderea unui segment este (icircn mod evident) apariţia 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 icircn varianta iniţială nu

permite decacirct confirmări pozitive singurul lucru pe care receptorul icircl poate face este ca la fiecare

segment out-of-order primit să trimită o confirmare indicacircnd prin aceasta că la el continuă să

vină segmente icircnsă cel indicat de numărul de secvenţă de confirmare lipseşte Primirea acestor

confirmări multiple este al doilea mod icircn care transmiţătorul poate afla de apariţia congestiei

Algoritmul ce trebuie aplicat icircn momentul icircn care se detectează apariţia congestiei este cunoscut

sub numele de ``evitarea congestiei (congestion avoidence) Principiul care stă la baza lui este

ca la apariţia congestiei fie să se treacă la o incrementare liniară a dimensiunii ferestrei dacă

congestia a fost detectată ca urmare a primirii unor confirmări identice repetate fie să se reia

slow start-ul icircn cazul icircn care congestia s-a detectat prin expirarea unui timer de timeout

Implementarea acestui algoritm se bazează pe utilizarea unui nou contor (sstresh) care să indice

dimensiunea ferestrei de la care se trece de la incrementarea exponenţială la cea liniară

Algoritmul efectiv este următorul

1 la stabilirea unei noi conexiuni se pleacă cu sstresh iniţializat la valoare de 64K şi cwnd

la dimensiunea unui segment

2 trimiterea de segmente se face fără a depăşi minimul dintre fereastra publicată de partener

(pentru a nu depăşi capacitatea de procesesare a partenerului) şi cwnd-ul curent (pentru a

nu depăşi limita impusă de capacitatea reţelei)

3 la apariţia congestiei sstresh este setat la jumătatea valorii ferestrei curente (minimul

dintre fereastra anunţată de partener şi cwnd icircnsă cel puţin dimensiunea corespunzătoare

pentru două segmente) dacă congestia a fost detectată prin expirarea unui timer de

timeout atunci cwnd este iniţializat cu dimensiunea unui segment

4 la primirea unei confirmări incrementarea se face icircn două moduri icircn funcţie de relaţie icircn

care se află cwnd şi sstresh

1 dacă cwnd e mai mic sau egal cu sstresh se face incrementarea exponenţială

caracteristică slow start-ului (care de fapt nu e deloc slow icircn cazul de faţă)

2 dacă cwnd e mai mare ca sstresh atunci se face o incrementare cu dimensiunea

unui segment

Fast Retransmission Fast Recovery

După cum am văzut un receptor care primeşte segmente out-of-order va trimite transmiţătorului

confirmări duplicate Algoritmul denumit ``fast retransmission recomandă următoarele două

comportamenet

1 un receptor care detectează segmente out-of order trebuie să nu icircntacircrzie trimiterea de

confirmări (după cum am văzut icircn general confimările sunt icircntacircrziate micşora numărul de

pachete fără date care sunt transferate)

2 un transmiţător care care primeşte mai mult de trei confirmări duplicate trebuie să

retrimită segmentul indicat ca fiind neprimit de confirmările icircn cauză fără a aştepta

expirarea timer-ul de timeout

Algoritmul de ``fast recovery icircncearcă să optimizeze şi mai mult comportamentul

transmiţătorului care detectează un număr de trei sau mai multe confimări duplicate Mai exact el

recomandă trecerea la actualizarea liniară a ferestrei (congestion avoidance) Acest tip de

comportament se poate justifica prin următorul raţionament deoarece icircncă mai sunt transferate

date icircntre cei doi parteneri (şi acest lucru se icircntacircmplă sigur de vreme ce sosesc confirmări

duplicate icircn cazul acesta) icircnseamnă că transferul nu este afectat de o congestie severă şi prin

urmare trecerea la slow start nu e (icircncă) necesară (slow start-ul eliberează aproape complet

canalul deoarece cwnd este resetat la dimensiunea unui singur segment)

Cei doi algoritmi pot fi implementaţi icircn felul următor

1 cacircnd se detectează trei confirmări consecutive identice se setează sstresh la jumătate din

valoarea cwnd se retransmite segmentul care s-a pierdut şi se setează cwnd la valoarea

egală cu sstresh plus dimensiunea a trei segmente (acest lucru va face ca algoritmul de

incrementare a cwnd să treacă la incrementare liniară)

2 la fiecare confirmare duplicată care mai soseşte se incrementează cwnd se incrementează

cu dimensiunea unui segment

3 cacircnd icircncetează primirea de confirmări duplicate (segmentul retrimis a ajuns cu bine la

receptor şi s-a trimis o confirmare care acoperă segmentul care se pierduse iniţial) cwnd

este setat la valoarea sstresh

Sindromul ``Silly Window

Protocoalele bazate pe fereastră glisantă (cum este şi TCP-ul) pot să ajungă icircn situaţia deloc

fericită de trimite un număr mare de segmente mici icircn loc de segmente de dimensiune maximă

Acest tip de comportament este cunoscut sub numele de sindromul ``silly window

O modalitate prin care TCP-ul poate să cadă victimă acestui tip de comportament este

deschiderea de ferestre cu dimensiune foarte mică O altă situaţia nefericită este cea icircn care un

transmiţător este ``lacom şi trimite date indiferent de cacirct de mică este fereastra (după cum vom

vedea imediat uneori are sens şi un astfel de comportament) Algoritmul de evitare a acestor

neajunsuri este următorul

1 un receptor nu trebuie să anunţe deschideri de ferestre mici Mai exact nu se recomandă

anunţarea unei incrementări a ferestrei mai mică decacirct dimensiunea unui segment (MSS)

sau jumătate din buffer-ul aflat la dispoziţia receptorului oricare din ele e mai mică

2 un transmiţător va trimite date doar icircn următoarele cazuri

1 se poate trimite un segment icircntreg

2 se poate trimite jumătate din dimensiunea celei mai mari ferestre pe care

partenerul a publicat-o pacircnă acum

3 toate datele trimise pacircnă acum au fost confirmate sau algoritmul Nagle este

dezactivat şi se trimit toate datele care sunt icircn buffer-ul de trimitere

Cacircteva justificări cazul 2b tratează cazul icircn care partenerul anunţă ferestre mai mici decacirct

dimensiunea unui segment iar cazul 2c impune condiţiile respectării algoritmului Nagle după

cum se vede dacă algoritmul Nagle este activ şi s-au acumulat destul date mai exact cacirct

dimensiunea unui segment el va fi trimis chiar dacă există segmente neconfirmate Pentru

implementarea comportamentului impus de 2b un transmiţător trebuie să ţină evidenţa celei mai

mari ferestre pe care partenerul a anunţat-o Ţinacircnd seama că dimensiunea acestor buffer-e nu se

modifică acest mod de a icircncerca determinarea lor este suficient

O altă problemă legată tot de ferestre este cazul icircnchiderii acesteia Un mod icircn care s-ar putea

anunţa redeschiderea este trimiterea de către receptor a unei confirmări (duplicat) care să anunţe

redeschiderea la o anumită valoare a ferestrei Deoarece acest pachet nu trebuie confirmat icircn mod

special şi s-ar putea să se piardă se poate ajunge icircn situaţia icircn care receptorul a anunţat

redeschiderea ferestrei segmentul s-a pierdut iar transmiţătorul icircncă mai icircl mai aşteaptă pentru a

putea continua transferul Rezolvarea la această problemă s-a făcut prin impunerea unui alt

comportament

1 transmiţătorul va trimite segmente cu dimensiunea datelor de un octet prin care sondează

deschiderea ferestrei intervalul la care se sondează redeschiderea ferestrei se dublează

(exponenţial backoff) icircn RFC 793 dimensiunea maximă recomandată este de 2 minute

icircnsă icircn RFC 1122 se specifică că maximul este acelaşi cu cel din cazul retransmisiei (240

secunde)

2 receptorul trebuie să refuze aceste pachete răspunzacircnd cu segmente de confirmare care

indică neprimirea octetului respectiv

Observaţie timer-ul special necesar pentru implementare la transmiţător a comportamentului de mai sus este cunoscut sub numele de ``TCP Persistent Timer Numele este justificat de faptul că sondarea deschiderii se va face pacircnă cacircnd fie fereastra se deschide fie conexiunea se icircntrerupe TCP Keepalive Timer

Un lucru interesant despre TCP este faptul că dacă nivelele superioare nu comunică nimic icircntre

ele pentru o perioadă lungă 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 icircn care au trecut cu succes de faza stabilirii legăturii Dacă nivelurile

inferioare (reţeaIP fizic) devin temporar indisponibile cacirct tip cei doi nu vor să comunice atunci

acest lucru nu va perturba icircn nici un fel activitatea şi acest lucru este acceptabil Problemele

icircncep să apară icircn momentul icircn care cei doi doresc să comunice şi nivelele inferioare nu mai

permit acest lucru Evident că cel care va dori să comunice ceva va detecta icircntreruperea legăturii

şi va icircnchide conexiunea Ce se icircntacircmplă icircnsă dacă celălalt capăt nu are nimic de comunicat (de

exemplu este un server care oferă anumite servicii) Pentru el legătura va fi icircn continuare activă

şi icircn general anumite resurse vor fi rezervate pentru aceasta Rezolvarea acestei situaţii este dată

de introducerea unei mecanism de sondare a stării legăturii pe baza unui timer (TCP Keepalive

Timer) care se declanşează din două icircn două ore La fiecare expirare a timer-ului se trimite un

segment fără date care confirmă datele primite pacircnă atunci Răspunsul care trebuie primit este tot

un segment fără date care confirmă datele primite de partener (practic o re-publicare a stării celor

doi parteneri) Dacă răspunsul nu este primit timp de 75 secunde atunci segmentul va fi retrimis

Dacă după 10 astfel de icircncercări tot nu s-a primit nici un răspuns atunci conexiunea se va

considera terminată şi se va anunţa nivelul superior asupra acestui lucru

Observaţii

dacă o staţie primeşte segmente de keepalive despre conexiuni care nu mai sunt active

(de exemplu a fost resetat) atunci va răspunde cu segmente de reset (acesta e un procedeu

standard)

RFC 1122 specifică că facilitatea de keepalive trebuie activată icircn mod explicit

3 Studii de caz

Subsections

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

1 Fragmentarea pachetelor UDP

Deoarece UDP-ul este un serviciu fără conexiune toate datele pe care le primeşte de la nivelul

superior sunt icircncapsulate icircntr-o singură datagramă UDP care apoi va forma un pachet IP Dacă

pachetul IP astfel obţinut este prea mare atunci mecanismele IP de fragmentare icircl vor sparge icircn

bucăţi Exemplul următor icircncearcă să studieze exact acest fenomen

Pe maşina athos rulează un server de UDP pe portul 50007 Pe o altă maşină frodo aflată icircn

reţeaua locală este rulat un client care poate fi configurat să trimită un pachet UDP de o anumită

lungime Pentru a putea observa ce se icircntacircmplă pe athos este rulat tcpdump

Deoarece MTU-ul pentru o reţea Ethernet este icircn general 1500 şi antetul IP plus cel UDP ocupă

20 + 8 = 28 octeţi o datagramă UDP de dimensiune 1472 ar trebui sa fie trimisă nefragmentată

Pentru siguranţă folosind clientul de pe athos s-a trimis mai icircntacirci o datagramă UDP cu 1471

octeţi de date şi apoi icircncă una cu 1472 Pentru ambele tcpdump a indicat trimiterea lor fără

fragmentare

182556721144 frodonoi33274 gt athosnoi50007 udp 1471 (DF) (ttl 64 id

51481 len 1499)

182559846764 frodonoi33274 gt athosnoi50007 udp 1472 (DF) (ttl 64 id

51793 len 1500)

La o dimensiune de 1473 ar trebui ca trimiterea să genereze două pachete IP unul care să

conţină primii antetul UDP plus primii 1472 octeţi de date şi icircncă un pachet IP care conţine un

singur octet Iată ce indică tcpdump-ul

182605705813 frodonoi gt athosnoi udp (frag 3627411480) (ttl 64 len

21)

182605706116 frodonoi33274 gt athosnoi50007 udp 1473 (frag

3627414800+) (ttl 64 len 1500)

Intr-adevăr au fost generate două pachete IP

primul conţine doar un singur octet de date şi reprezintă ultimul fragment (bitul de more

fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest

lucru) care a fost spartă icircn bucăţi deplasamentul octetului primit in datagrama originală

este 1480

al doilea pachet este primul fragment din datagrama UDP şi conţine antetul UDP (din

cauza asta datele efective ocupă doar 1480 octeţi) deplasamentul este 0 şi bitul de more

fragments este setat (acest lucru este indicat de semnul ``+ de după deplasament)

După cum se poate observa ambele pachete poartă acelaşi număr de identificare (36274) Acest

lucru icircmpreună cu informaţiile date de flag-ul more fragments permite reconstrucţia la

destinaţie a datagramei UDP originale O problemă a acestui mod de fragmentare e că icircn cazul

pierderii unui fragment icircntreaga datagramă va fi compromisă şi va trebui retrimisă icircn icircntregime

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 16: udp tcp

nivel (aplicaţie) Dacă datele vin prea repede pentru viteza cu care clientul procesează datele

fereastra fereastra se va dimiua şi chiar icircnchide (acest lucru se realizează anunţacircnd o fereastră de

dimensiune zero) Cum se realizează efectiv redeschiderea vom analiza icircntr-un capitol viitor

Slow start

Un transfer de date TCP poate să icircnceapă prin transmiterea de segmente pacircnă la umplerea

icircntregii ferestre după care fie se primesc confirmări care vor permite unor noi pachete să fie

trimise fie vor expira timer-ele de retransmisie şi se va icircncepe retrimiterea pachetelor de la

icircnceputul ferestrei Din păcate un astfel de comportament poate duce la pomparea icircn reţea a unui

număr de pachete prea mare pentru capacitatea disponibilă efectiv icircnrăutăţind congestia Pentru

a evita acest lucru s-a propus următoarea soluţie4 iniţial se trimite un segment după primirea

confirmării lui se trimit două segmente după sosirea confirmărilor pentru ele se trimit patru

segmente şi aşa mai departe La un moment dat fie vor icircncepe să se piardă segmente (un indiciu

că s-a atins capacitatea maximă a canalului) fie se va umple fereastra pe care o anunţă cel care

primeşte Trebuie să remarcam că datorită creşterii exponenţiale a numărului de segmente se va

atinge destul de repede una din cele două situaţii

Modalitatea efectivă de implementare a acestui algoritm are la bază utilizarea unei ferestre de

congestie (congestion window cwnd) care este iniţializată cu dimensiunea unui segment (cwnd

se calculează icircn octeţi) şi la fiecare pas este dublată fereastra efectivă din cadrul căreia se pot

trimite segmente este dată de minimul dintre ultima fereastra comunicată de partener şi cwnd

Footnotes

soluţie4

Soluţia aparţine lui V Jacobson şi a fost prezentată icircn 1988 la conferinţă ACM

SIGCOMM-88

Retransmission Timeout (RTO) şi Round-Trip Time (RTT)

Deoarece TCP trebuie să funcţioneze icircn condiţii variate de latenţă modul icircn care se face

retransmiterea trebuie să fie cacirct mai flexibil (şi simplu icircn acelaşi timp pentru a introduce un

overhead cacirct mai mic) Timpul cacirct se aşteaptă venirea unei confirmări (retransmission timeout

RTO) este calculat prin cronometrarea timpului care icirci ia unui segment trimis să fie confirmat

Pentru o anumită conexiune se cronometrează cacircte un singur segment la un moment dat iar pe

baza RTT-ului măsurat se actualizează valoare RTO-ului

Icircn RFC 793 formula de calcul a RTO-ului este următoarea

unde este ultimul RTT măsurat este o estimare ponderată pentru RTT este un coeficient

de ponderare care icircn general are valoarea iar este un coeficient cu o valoare recomandată

de După cum se poate observa icircn valoarea lui este inclusă icircn mare măsură vechea valoarea

Icircn acest fel ajustarea RTT-ului se face treptat Din păcate acest mod de calcul nu funcţionează

bine la variaţii mari ale RTT-ului ducacircnd la creşterea numărului de retransmisii exact atunci

cacircnd fenomenul de congestie icircncepe să apară

Pentru a remedia aceste neajunsuri V Jacobsen a propus icircn 1988 o nouă metodă de calcul o

metodă care ţine seama seamă şi de modul icircn care variază diferenţa dintre RTT-uri Formulele

folosite sunt următoarele

unde este un estimare pentru media RTT-urilor este o estimare pentru abaterea RTT-urilor

faţă de medie (o aproximaţie suficientă pentru abaterea pătratică medie care icircnsă este mult mai

costisitor de calculat) este diferenţa dintre RTT-ul măsurat ( ) şi estimarea curentă ( )

Coeficientul cu care este actualizată estimarea curentă are valoarea de iar cel cu care este

actualizat estimarea abaterii este La stabilirea unei conexiuni valorile pentru şi sunt

alese astfel icircncacirct să rezulte un RTT de secunde şi un de 3 secunde (aceste recomandări

sunt făcute de RFC 1122)

Dacă pentru un anumit segment nu se primeşte confirmarea icircn intervalul indicat de el va fi

retrimis şi noul este dublat Valoarea maximă admisă pentru este de 240 secunde

Deoarece icircn cazul retrimiterilor nu se poate determina cu exactitate căruia din segmentele trimise

aparţine confirmarea actualizarea estimărilor este amacircnată pacircnă cacircnd se reuşeşte trimiterea

corectă (s-a primit confirmare) fără retransmitere(``din prima) a unui segment Acest artificiu

(deloc neimportant) care permite evitarea actualizarea eronată a estimărilor este cunoscut sub

numele de algoritmul lui Karn şi a fost propus icircn 1987 de P Karn şi C Partridge

Evitarea congestiei

Dacă cei doi parteneri care comunică prelucrează datele suficient de repede şi vor să transfere un

volum mare de date atunci limitarea de care se vor lovi este cea dată de viteza reţelei Din cauza

modului ``best-effort pe care IP-ul icircl oferă cacircnd canalul de comunicaţie este saturat o parte din

segmentele TCP se vor pierde Icircn mod poate paradoxal atacirct transmiţătorului cacirct şi receptorul se

pot afla icircn poziţia de a fi primii icircn detectarea pierderii unui segment Unul din indiciile de la

transmiţător care semnalează pierderea unui segment este (icircn mod evident) apariţia 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 icircn varianta iniţială nu

permite decacirct confirmări pozitive singurul lucru pe care receptorul icircl poate face este ca la fiecare

segment out-of-order primit să trimită o confirmare indicacircnd prin aceasta că la el continuă să

vină segmente icircnsă cel indicat de numărul de secvenţă de confirmare lipseşte Primirea acestor

confirmări multiple este al doilea mod icircn care transmiţătorul poate afla de apariţia congestiei

Algoritmul ce trebuie aplicat icircn momentul icircn care se detectează apariţia congestiei este cunoscut

sub numele de ``evitarea congestiei (congestion avoidence) Principiul care stă la baza lui este

ca la apariţia congestiei fie să se treacă la o incrementare liniară a dimensiunii ferestrei dacă

congestia a fost detectată ca urmare a primirii unor confirmări identice repetate fie să se reia

slow start-ul icircn cazul icircn care congestia s-a detectat prin expirarea unui timer de timeout

Implementarea acestui algoritm se bazează pe utilizarea unui nou contor (sstresh) care să indice

dimensiunea ferestrei de la care se trece de la incrementarea exponenţială la cea liniară

Algoritmul efectiv este următorul

1 la stabilirea unei noi conexiuni se pleacă cu sstresh iniţializat la valoare de 64K şi cwnd

la dimensiunea unui segment

2 trimiterea de segmente se face fără a depăşi minimul dintre fereastra publicată de partener

(pentru a nu depăşi capacitatea de procesesare a partenerului) şi cwnd-ul curent (pentru a

nu depăşi limita impusă de capacitatea reţelei)

3 la apariţia congestiei sstresh este setat la jumătatea valorii ferestrei curente (minimul

dintre fereastra anunţată de partener şi cwnd icircnsă cel puţin dimensiunea corespunzătoare

pentru două segmente) dacă congestia a fost detectată prin expirarea unui timer de

timeout atunci cwnd este iniţializat cu dimensiunea unui segment

4 la primirea unei confirmări incrementarea se face icircn două moduri icircn funcţie de relaţie icircn

care se află cwnd şi sstresh

1 dacă cwnd e mai mic sau egal cu sstresh se face incrementarea exponenţială

caracteristică slow start-ului (care de fapt nu e deloc slow icircn cazul de faţă)

2 dacă cwnd e mai mare ca sstresh atunci se face o incrementare cu dimensiunea

unui segment

Fast Retransmission Fast Recovery

După cum am văzut un receptor care primeşte segmente out-of-order va trimite transmiţătorului

confirmări duplicate Algoritmul denumit ``fast retransmission recomandă următoarele două

comportamenet

1 un receptor care detectează segmente out-of order trebuie să nu icircntacircrzie trimiterea de

confirmări (după cum am văzut icircn general confimările sunt icircntacircrziate micşora numărul de

pachete fără date care sunt transferate)

2 un transmiţător care care primeşte mai mult de trei confirmări duplicate trebuie să

retrimită segmentul indicat ca fiind neprimit de confirmările icircn cauză fără a aştepta

expirarea timer-ul de timeout

Algoritmul de ``fast recovery icircncearcă să optimizeze şi mai mult comportamentul

transmiţătorului care detectează un număr de trei sau mai multe confimări duplicate Mai exact el

recomandă trecerea la actualizarea liniară a ferestrei (congestion avoidance) Acest tip de

comportament se poate justifica prin următorul raţionament deoarece icircncă mai sunt transferate

date icircntre cei doi parteneri (şi acest lucru se icircntacircmplă sigur de vreme ce sosesc confirmări

duplicate icircn cazul acesta) icircnseamnă că transferul nu este afectat de o congestie severă şi prin

urmare trecerea la slow start nu e (icircncă) necesară (slow start-ul eliberează aproape complet

canalul deoarece cwnd este resetat la dimensiunea unui singur segment)

Cei doi algoritmi pot fi implementaţi icircn felul următor

1 cacircnd se detectează trei confirmări consecutive identice se setează sstresh la jumătate din

valoarea cwnd se retransmite segmentul care s-a pierdut şi se setează cwnd la valoarea

egală cu sstresh plus dimensiunea a trei segmente (acest lucru va face ca algoritmul de

incrementare a cwnd să treacă la incrementare liniară)

2 la fiecare confirmare duplicată care mai soseşte se incrementează cwnd se incrementează

cu dimensiunea unui segment

3 cacircnd icircncetează primirea de confirmări duplicate (segmentul retrimis a ajuns cu bine la

receptor şi s-a trimis o confirmare care acoperă segmentul care se pierduse iniţial) cwnd

este setat la valoarea sstresh

Sindromul ``Silly Window

Protocoalele bazate pe fereastră glisantă (cum este şi TCP-ul) pot să ajungă icircn situaţia deloc

fericită de trimite un număr mare de segmente mici icircn loc de segmente de dimensiune maximă

Acest tip de comportament este cunoscut sub numele de sindromul ``silly window

O modalitate prin care TCP-ul poate să cadă victimă acestui tip de comportament este

deschiderea de ferestre cu dimensiune foarte mică O altă situaţia nefericită este cea icircn care un

transmiţător este ``lacom şi trimite date indiferent de cacirct de mică este fereastra (după cum vom

vedea imediat uneori are sens şi un astfel de comportament) Algoritmul de evitare a acestor

neajunsuri este următorul

1 un receptor nu trebuie să anunţe deschideri de ferestre mici Mai exact nu se recomandă

anunţarea unei incrementări a ferestrei mai mică decacirct dimensiunea unui segment (MSS)

sau jumătate din buffer-ul aflat la dispoziţia receptorului oricare din ele e mai mică

2 un transmiţător va trimite date doar icircn următoarele cazuri

1 se poate trimite un segment icircntreg

2 se poate trimite jumătate din dimensiunea celei mai mari ferestre pe care

partenerul a publicat-o pacircnă acum

3 toate datele trimise pacircnă acum au fost confirmate sau algoritmul Nagle este

dezactivat şi se trimit toate datele care sunt icircn buffer-ul de trimitere

Cacircteva justificări cazul 2b tratează cazul icircn care partenerul anunţă ferestre mai mici decacirct

dimensiunea unui segment iar cazul 2c impune condiţiile respectării algoritmului Nagle după

cum se vede dacă algoritmul Nagle este activ şi s-au acumulat destul date mai exact cacirct

dimensiunea unui segment el va fi trimis chiar dacă există segmente neconfirmate Pentru

implementarea comportamentului impus de 2b un transmiţător trebuie să ţină evidenţa celei mai

mari ferestre pe care partenerul a anunţat-o Ţinacircnd seama că dimensiunea acestor buffer-e nu se

modifică acest mod de a icircncerca determinarea lor este suficient

O altă problemă legată tot de ferestre este cazul icircnchiderii acesteia Un mod icircn care s-ar putea

anunţa redeschiderea este trimiterea de către receptor a unei confirmări (duplicat) care să anunţe

redeschiderea la o anumită valoare a ferestrei Deoarece acest pachet nu trebuie confirmat icircn mod

special şi s-ar putea să se piardă se poate ajunge icircn situaţia icircn care receptorul a anunţat

redeschiderea ferestrei segmentul s-a pierdut iar transmiţătorul icircncă mai icircl mai aşteaptă pentru a

putea continua transferul Rezolvarea la această problemă s-a făcut prin impunerea unui alt

comportament

1 transmiţătorul va trimite segmente cu dimensiunea datelor de un octet prin care sondează

deschiderea ferestrei intervalul la care se sondează redeschiderea ferestrei se dublează

(exponenţial backoff) icircn RFC 793 dimensiunea maximă recomandată este de 2 minute

icircnsă icircn RFC 1122 se specifică că maximul este acelaşi cu cel din cazul retransmisiei (240

secunde)

2 receptorul trebuie să refuze aceste pachete răspunzacircnd cu segmente de confirmare care

indică neprimirea octetului respectiv

Observaţie timer-ul special necesar pentru implementare la transmiţător a comportamentului de mai sus este cunoscut sub numele de ``TCP Persistent Timer Numele este justificat de faptul că sondarea deschiderii se va face pacircnă cacircnd fie fereastra se deschide fie conexiunea se icircntrerupe TCP Keepalive Timer

Un lucru interesant despre TCP este faptul că dacă nivelele superioare nu comunică nimic icircntre

ele pentru o perioadă lungă 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 icircn care au trecut cu succes de faza stabilirii legăturii Dacă nivelurile

inferioare (reţeaIP fizic) devin temporar indisponibile cacirct tip cei doi nu vor să comunice atunci

acest lucru nu va perturba icircn nici un fel activitatea şi acest lucru este acceptabil Problemele

icircncep să apară icircn momentul icircn care cei doi doresc să comunice şi nivelele inferioare nu mai

permit acest lucru Evident că cel care va dori să comunice ceva va detecta icircntreruperea legăturii

şi va icircnchide conexiunea Ce se icircntacircmplă icircnsă dacă celălalt capăt nu are nimic de comunicat (de

exemplu este un server care oferă anumite servicii) Pentru el legătura va fi icircn continuare activă

şi icircn general anumite resurse vor fi rezervate pentru aceasta Rezolvarea acestei situaţii este dată

de introducerea unei mecanism de sondare a stării legăturii pe baza unui timer (TCP Keepalive

Timer) care se declanşează din două icircn două ore La fiecare expirare a timer-ului se trimite un

segment fără date care confirmă datele primite pacircnă atunci Răspunsul care trebuie primit este tot

un segment fără date care confirmă datele primite de partener (practic o re-publicare a stării celor

doi parteneri) Dacă răspunsul nu este primit timp de 75 secunde atunci segmentul va fi retrimis

Dacă după 10 astfel de icircncercări tot nu s-a primit nici un răspuns atunci conexiunea se va

considera terminată şi se va anunţa nivelul superior asupra acestui lucru

Observaţii

dacă o staţie primeşte segmente de keepalive despre conexiuni care nu mai sunt active

(de exemplu a fost resetat) atunci va răspunde cu segmente de reset (acesta e un procedeu

standard)

RFC 1122 specifică că facilitatea de keepalive trebuie activată icircn mod explicit

3 Studii de caz

Subsections

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

1 Fragmentarea pachetelor UDP

Deoarece UDP-ul este un serviciu fără conexiune toate datele pe care le primeşte de la nivelul

superior sunt icircncapsulate icircntr-o singură datagramă UDP care apoi va forma un pachet IP Dacă

pachetul IP astfel obţinut este prea mare atunci mecanismele IP de fragmentare icircl vor sparge icircn

bucăţi Exemplul următor icircncearcă să studieze exact acest fenomen

Pe maşina athos rulează un server de UDP pe portul 50007 Pe o altă maşină frodo aflată icircn

reţeaua locală este rulat un client care poate fi configurat să trimită un pachet UDP de o anumită

lungime Pentru a putea observa ce se icircntacircmplă pe athos este rulat tcpdump

Deoarece MTU-ul pentru o reţea Ethernet este icircn general 1500 şi antetul IP plus cel UDP ocupă

20 + 8 = 28 octeţi o datagramă UDP de dimensiune 1472 ar trebui sa fie trimisă nefragmentată

Pentru siguranţă folosind clientul de pe athos s-a trimis mai icircntacirci o datagramă UDP cu 1471

octeţi de date şi apoi icircncă una cu 1472 Pentru ambele tcpdump a indicat trimiterea lor fără

fragmentare

182556721144 frodonoi33274 gt athosnoi50007 udp 1471 (DF) (ttl 64 id

51481 len 1499)

182559846764 frodonoi33274 gt athosnoi50007 udp 1472 (DF) (ttl 64 id

51793 len 1500)

La o dimensiune de 1473 ar trebui ca trimiterea să genereze două pachete IP unul care să

conţină primii antetul UDP plus primii 1472 octeţi de date şi icircncă un pachet IP care conţine un

singur octet Iată ce indică tcpdump-ul

182605705813 frodonoi gt athosnoi udp (frag 3627411480) (ttl 64 len

21)

182605706116 frodonoi33274 gt athosnoi50007 udp 1473 (frag

3627414800+) (ttl 64 len 1500)

Intr-adevăr au fost generate două pachete IP

primul conţine doar un singur octet de date şi reprezintă ultimul fragment (bitul de more

fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest

lucru) care a fost spartă icircn bucăţi deplasamentul octetului primit in datagrama originală

este 1480

al doilea pachet este primul fragment din datagrama UDP şi conţine antetul UDP (din

cauza asta datele efective ocupă doar 1480 octeţi) deplasamentul este 0 şi bitul de more

fragments este setat (acest lucru este indicat de semnul ``+ de după deplasament)

După cum se poate observa ambele pachete poartă acelaşi număr de identificare (36274) Acest

lucru icircmpreună cu informaţiile date de flag-ul more fragments permite reconstrucţia la

destinaţie a datagramei UDP originale O problemă a acestui mod de fragmentare e că icircn cazul

pierderii unui fragment icircntreaga datagramă va fi compromisă şi va trebui retrimisă icircn icircntregime

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 17: udp tcp

unde este ultimul RTT măsurat este o estimare ponderată pentru RTT este un coeficient

de ponderare care icircn general are valoarea iar este un coeficient cu o valoare recomandată

de După cum se poate observa icircn valoarea lui este inclusă icircn mare măsură vechea valoarea

Icircn acest fel ajustarea RTT-ului se face treptat Din păcate acest mod de calcul nu funcţionează

bine la variaţii mari ale RTT-ului ducacircnd la creşterea numărului de retransmisii exact atunci

cacircnd fenomenul de congestie icircncepe să apară

Pentru a remedia aceste neajunsuri V Jacobsen a propus icircn 1988 o nouă metodă de calcul o

metodă care ţine seama seamă şi de modul icircn care variază diferenţa dintre RTT-uri Formulele

folosite sunt următoarele

unde este un estimare pentru media RTT-urilor este o estimare pentru abaterea RTT-urilor

faţă de medie (o aproximaţie suficientă pentru abaterea pătratică medie care icircnsă este mult mai

costisitor de calculat) este diferenţa dintre RTT-ul măsurat ( ) şi estimarea curentă ( )

Coeficientul cu care este actualizată estimarea curentă are valoarea de iar cel cu care este

actualizat estimarea abaterii este La stabilirea unei conexiuni valorile pentru şi sunt

alese astfel icircncacirct să rezulte un RTT de secunde şi un de 3 secunde (aceste recomandări

sunt făcute de RFC 1122)

Dacă pentru un anumit segment nu se primeşte confirmarea icircn intervalul indicat de el va fi

retrimis şi noul este dublat Valoarea maximă admisă pentru este de 240 secunde

Deoarece icircn cazul retrimiterilor nu se poate determina cu exactitate căruia din segmentele trimise

aparţine confirmarea actualizarea estimărilor este amacircnată pacircnă cacircnd se reuşeşte trimiterea

corectă (s-a primit confirmare) fără retransmitere(``din prima) a unui segment Acest artificiu

(deloc neimportant) care permite evitarea actualizarea eronată a estimărilor este cunoscut sub

numele de algoritmul lui Karn şi a fost propus icircn 1987 de P Karn şi C Partridge

Evitarea congestiei

Dacă cei doi parteneri care comunică prelucrează datele suficient de repede şi vor să transfere un

volum mare de date atunci limitarea de care se vor lovi este cea dată de viteza reţelei Din cauza

modului ``best-effort pe care IP-ul icircl oferă cacircnd canalul de comunicaţie este saturat o parte din

segmentele TCP se vor pierde Icircn mod poate paradoxal atacirct transmiţătorului cacirct şi receptorul se

pot afla icircn poziţia de a fi primii icircn detectarea pierderii unui segment Unul din indiciile de la

transmiţător care semnalează pierderea unui segment este (icircn mod evident) apariţia 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 icircn varianta iniţială nu

permite decacirct confirmări pozitive singurul lucru pe care receptorul icircl poate face este ca la fiecare

segment out-of-order primit să trimită o confirmare indicacircnd prin aceasta că la el continuă să

vină segmente icircnsă cel indicat de numărul de secvenţă de confirmare lipseşte Primirea acestor

confirmări multiple este al doilea mod icircn care transmiţătorul poate afla de apariţia congestiei

Algoritmul ce trebuie aplicat icircn momentul icircn care se detectează apariţia congestiei este cunoscut

sub numele de ``evitarea congestiei (congestion avoidence) Principiul care stă la baza lui este

ca la apariţia congestiei fie să se treacă la o incrementare liniară a dimensiunii ferestrei dacă

congestia a fost detectată ca urmare a primirii unor confirmări identice repetate fie să se reia

slow start-ul icircn cazul icircn care congestia s-a detectat prin expirarea unui timer de timeout

Implementarea acestui algoritm se bazează pe utilizarea unui nou contor (sstresh) care să indice

dimensiunea ferestrei de la care se trece de la incrementarea exponenţială la cea liniară

Algoritmul efectiv este următorul

1 la stabilirea unei noi conexiuni se pleacă cu sstresh iniţializat la valoare de 64K şi cwnd

la dimensiunea unui segment

2 trimiterea de segmente se face fără a depăşi minimul dintre fereastra publicată de partener

(pentru a nu depăşi capacitatea de procesesare a partenerului) şi cwnd-ul curent (pentru a

nu depăşi limita impusă de capacitatea reţelei)

3 la apariţia congestiei sstresh este setat la jumătatea valorii ferestrei curente (minimul

dintre fereastra anunţată de partener şi cwnd icircnsă cel puţin dimensiunea corespunzătoare

pentru două segmente) dacă congestia a fost detectată prin expirarea unui timer de

timeout atunci cwnd este iniţializat cu dimensiunea unui segment

4 la primirea unei confirmări incrementarea se face icircn două moduri icircn funcţie de relaţie icircn

care se află cwnd şi sstresh

1 dacă cwnd e mai mic sau egal cu sstresh se face incrementarea exponenţială

caracteristică slow start-ului (care de fapt nu e deloc slow icircn cazul de faţă)

2 dacă cwnd e mai mare ca sstresh atunci se face o incrementare cu dimensiunea

unui segment

Fast Retransmission Fast Recovery

După cum am văzut un receptor care primeşte segmente out-of-order va trimite transmiţătorului

confirmări duplicate Algoritmul denumit ``fast retransmission recomandă următoarele două

comportamenet

1 un receptor care detectează segmente out-of order trebuie să nu icircntacircrzie trimiterea de

confirmări (după cum am văzut icircn general confimările sunt icircntacircrziate micşora numărul de

pachete fără date care sunt transferate)

2 un transmiţător care care primeşte mai mult de trei confirmări duplicate trebuie să

retrimită segmentul indicat ca fiind neprimit de confirmările icircn cauză fără a aştepta

expirarea timer-ul de timeout

Algoritmul de ``fast recovery icircncearcă să optimizeze şi mai mult comportamentul

transmiţătorului care detectează un număr de trei sau mai multe confimări duplicate Mai exact el

recomandă trecerea la actualizarea liniară a ferestrei (congestion avoidance) Acest tip de

comportament se poate justifica prin următorul raţionament deoarece icircncă mai sunt transferate

date icircntre cei doi parteneri (şi acest lucru se icircntacircmplă sigur de vreme ce sosesc confirmări

duplicate icircn cazul acesta) icircnseamnă că transferul nu este afectat de o congestie severă şi prin

urmare trecerea la slow start nu e (icircncă) necesară (slow start-ul eliberează aproape complet

canalul deoarece cwnd este resetat la dimensiunea unui singur segment)

Cei doi algoritmi pot fi implementaţi icircn felul următor

1 cacircnd se detectează trei confirmări consecutive identice se setează sstresh la jumătate din

valoarea cwnd se retransmite segmentul care s-a pierdut şi se setează cwnd la valoarea

egală cu sstresh plus dimensiunea a trei segmente (acest lucru va face ca algoritmul de

incrementare a cwnd să treacă la incrementare liniară)

2 la fiecare confirmare duplicată care mai soseşte se incrementează cwnd se incrementează

cu dimensiunea unui segment

3 cacircnd icircncetează primirea de confirmări duplicate (segmentul retrimis a ajuns cu bine la

receptor şi s-a trimis o confirmare care acoperă segmentul care se pierduse iniţial) cwnd

este setat la valoarea sstresh

Sindromul ``Silly Window

Protocoalele bazate pe fereastră glisantă (cum este şi TCP-ul) pot să ajungă icircn situaţia deloc

fericită de trimite un număr mare de segmente mici icircn loc de segmente de dimensiune maximă

Acest tip de comportament este cunoscut sub numele de sindromul ``silly window

O modalitate prin care TCP-ul poate să cadă victimă acestui tip de comportament este

deschiderea de ferestre cu dimensiune foarte mică O altă situaţia nefericită este cea icircn care un

transmiţător este ``lacom şi trimite date indiferent de cacirct de mică este fereastra (după cum vom

vedea imediat uneori are sens şi un astfel de comportament) Algoritmul de evitare a acestor

neajunsuri este următorul

1 un receptor nu trebuie să anunţe deschideri de ferestre mici Mai exact nu se recomandă

anunţarea unei incrementări a ferestrei mai mică decacirct dimensiunea unui segment (MSS)

sau jumătate din buffer-ul aflat la dispoziţia receptorului oricare din ele e mai mică

2 un transmiţător va trimite date doar icircn următoarele cazuri

1 se poate trimite un segment icircntreg

2 se poate trimite jumătate din dimensiunea celei mai mari ferestre pe care

partenerul a publicat-o pacircnă acum

3 toate datele trimise pacircnă acum au fost confirmate sau algoritmul Nagle este

dezactivat şi se trimit toate datele care sunt icircn buffer-ul de trimitere

Cacircteva justificări cazul 2b tratează cazul icircn care partenerul anunţă ferestre mai mici decacirct

dimensiunea unui segment iar cazul 2c impune condiţiile respectării algoritmului Nagle după

cum se vede dacă algoritmul Nagle este activ şi s-au acumulat destul date mai exact cacirct

dimensiunea unui segment el va fi trimis chiar dacă există segmente neconfirmate Pentru

implementarea comportamentului impus de 2b un transmiţător trebuie să ţină evidenţa celei mai

mari ferestre pe care partenerul a anunţat-o Ţinacircnd seama că dimensiunea acestor buffer-e nu se

modifică acest mod de a icircncerca determinarea lor este suficient

O altă problemă legată tot de ferestre este cazul icircnchiderii acesteia Un mod icircn care s-ar putea

anunţa redeschiderea este trimiterea de către receptor a unei confirmări (duplicat) care să anunţe

redeschiderea la o anumită valoare a ferestrei Deoarece acest pachet nu trebuie confirmat icircn mod

special şi s-ar putea să se piardă se poate ajunge icircn situaţia icircn care receptorul a anunţat

redeschiderea ferestrei segmentul s-a pierdut iar transmiţătorul icircncă mai icircl mai aşteaptă pentru a

putea continua transferul Rezolvarea la această problemă s-a făcut prin impunerea unui alt

comportament

1 transmiţătorul va trimite segmente cu dimensiunea datelor de un octet prin care sondează

deschiderea ferestrei intervalul la care se sondează redeschiderea ferestrei se dublează

(exponenţial backoff) icircn RFC 793 dimensiunea maximă recomandată este de 2 minute

icircnsă icircn RFC 1122 se specifică că maximul este acelaşi cu cel din cazul retransmisiei (240

secunde)

2 receptorul trebuie să refuze aceste pachete răspunzacircnd cu segmente de confirmare care

indică neprimirea octetului respectiv

Observaţie timer-ul special necesar pentru implementare la transmiţător a comportamentului de mai sus este cunoscut sub numele de ``TCP Persistent Timer Numele este justificat de faptul că sondarea deschiderii se va face pacircnă cacircnd fie fereastra se deschide fie conexiunea se icircntrerupe TCP Keepalive Timer

Un lucru interesant despre TCP este faptul că dacă nivelele superioare nu comunică nimic icircntre

ele pentru o perioadă lungă 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 icircn care au trecut cu succes de faza stabilirii legăturii Dacă nivelurile

inferioare (reţeaIP fizic) devin temporar indisponibile cacirct tip cei doi nu vor să comunice atunci

acest lucru nu va perturba icircn nici un fel activitatea şi acest lucru este acceptabil Problemele

icircncep să apară icircn momentul icircn care cei doi doresc să comunice şi nivelele inferioare nu mai

permit acest lucru Evident că cel care va dori să comunice ceva va detecta icircntreruperea legăturii

şi va icircnchide conexiunea Ce se icircntacircmplă icircnsă dacă celălalt capăt nu are nimic de comunicat (de

exemplu este un server care oferă anumite servicii) Pentru el legătura va fi icircn continuare activă

şi icircn general anumite resurse vor fi rezervate pentru aceasta Rezolvarea acestei situaţii este dată

de introducerea unei mecanism de sondare a stării legăturii pe baza unui timer (TCP Keepalive

Timer) care se declanşează din două icircn două ore La fiecare expirare a timer-ului se trimite un

segment fără date care confirmă datele primite pacircnă atunci Răspunsul care trebuie primit este tot

un segment fără date care confirmă datele primite de partener (practic o re-publicare a stării celor

doi parteneri) Dacă răspunsul nu este primit timp de 75 secunde atunci segmentul va fi retrimis

Dacă după 10 astfel de icircncercări tot nu s-a primit nici un răspuns atunci conexiunea se va

considera terminată şi se va anunţa nivelul superior asupra acestui lucru

Observaţii

dacă o staţie primeşte segmente de keepalive despre conexiuni care nu mai sunt active

(de exemplu a fost resetat) atunci va răspunde cu segmente de reset (acesta e un procedeu

standard)

RFC 1122 specifică că facilitatea de keepalive trebuie activată icircn mod explicit

3 Studii de caz

Subsections

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

1 Fragmentarea pachetelor UDP

Deoarece UDP-ul este un serviciu fără conexiune toate datele pe care le primeşte de la nivelul

superior sunt icircncapsulate icircntr-o singură datagramă UDP care apoi va forma un pachet IP Dacă

pachetul IP astfel obţinut este prea mare atunci mecanismele IP de fragmentare icircl vor sparge icircn

bucăţi Exemplul următor icircncearcă să studieze exact acest fenomen

Pe maşina athos rulează un server de UDP pe portul 50007 Pe o altă maşină frodo aflată icircn

reţeaua locală este rulat un client care poate fi configurat să trimită un pachet UDP de o anumită

lungime Pentru a putea observa ce se icircntacircmplă pe athos este rulat tcpdump

Deoarece MTU-ul pentru o reţea Ethernet este icircn general 1500 şi antetul IP plus cel UDP ocupă

20 + 8 = 28 octeţi o datagramă UDP de dimensiune 1472 ar trebui sa fie trimisă nefragmentată

Pentru siguranţă folosind clientul de pe athos s-a trimis mai icircntacirci o datagramă UDP cu 1471

octeţi de date şi apoi icircncă una cu 1472 Pentru ambele tcpdump a indicat trimiterea lor fără

fragmentare

182556721144 frodonoi33274 gt athosnoi50007 udp 1471 (DF) (ttl 64 id

51481 len 1499)

182559846764 frodonoi33274 gt athosnoi50007 udp 1472 (DF) (ttl 64 id

51793 len 1500)

La o dimensiune de 1473 ar trebui ca trimiterea să genereze două pachete IP unul care să

conţină primii antetul UDP plus primii 1472 octeţi de date şi icircncă un pachet IP care conţine un

singur octet Iată ce indică tcpdump-ul

182605705813 frodonoi gt athosnoi udp (frag 3627411480) (ttl 64 len

21)

182605706116 frodonoi33274 gt athosnoi50007 udp 1473 (frag

3627414800+) (ttl 64 len 1500)

Intr-adevăr au fost generate două pachete IP

primul conţine doar un singur octet de date şi reprezintă ultimul fragment (bitul de more

fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest

lucru) care a fost spartă icircn bucăţi deplasamentul octetului primit in datagrama originală

este 1480

al doilea pachet este primul fragment din datagrama UDP şi conţine antetul UDP (din

cauza asta datele efective ocupă doar 1480 octeţi) deplasamentul este 0 şi bitul de more

fragments este setat (acest lucru este indicat de semnul ``+ de după deplasament)

După cum se poate observa ambele pachete poartă acelaşi număr de identificare (36274) Acest

lucru icircmpreună cu informaţiile date de flag-ul more fragments permite reconstrucţia la

destinaţie a datagramei UDP originale O problemă a acestui mod de fragmentare e că icircn cazul

pierderii unui fragment icircntreaga datagramă va fi compromisă şi va trebui retrimisă icircn icircntregime

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 18: udp tcp

Evitarea congestiei

Dacă cei doi parteneri care comunică prelucrează datele suficient de repede şi vor să transfere un

volum mare de date atunci limitarea de care se vor lovi este cea dată de viteza reţelei Din cauza

modului ``best-effort pe care IP-ul icircl oferă cacircnd canalul de comunicaţie este saturat o parte din

segmentele TCP se vor pierde Icircn mod poate paradoxal atacirct transmiţătorului cacirct şi receptorul se

pot afla icircn poziţia de a fi primii icircn detectarea pierderii unui segment Unul din indiciile de la

transmiţător care semnalează pierderea unui segment este (icircn mod evident) apariţia 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 icircn varianta iniţială nu

permite decacirct confirmări pozitive singurul lucru pe care receptorul icircl poate face este ca la fiecare

segment out-of-order primit să trimită o confirmare indicacircnd prin aceasta că la el continuă să

vină segmente icircnsă cel indicat de numărul de secvenţă de confirmare lipseşte Primirea acestor

confirmări multiple este al doilea mod icircn care transmiţătorul poate afla de apariţia congestiei

Algoritmul ce trebuie aplicat icircn momentul icircn care se detectează apariţia congestiei este cunoscut

sub numele de ``evitarea congestiei (congestion avoidence) Principiul care stă la baza lui este

ca la apariţia congestiei fie să se treacă la o incrementare liniară a dimensiunii ferestrei dacă

congestia a fost detectată ca urmare a primirii unor confirmări identice repetate fie să se reia

slow start-ul icircn cazul icircn care congestia s-a detectat prin expirarea unui timer de timeout

Implementarea acestui algoritm se bazează pe utilizarea unui nou contor (sstresh) care să indice

dimensiunea ferestrei de la care se trece de la incrementarea exponenţială la cea liniară

Algoritmul efectiv este următorul

1 la stabilirea unei noi conexiuni se pleacă cu sstresh iniţializat la valoare de 64K şi cwnd

la dimensiunea unui segment

2 trimiterea de segmente se face fără a depăşi minimul dintre fereastra publicată de partener

(pentru a nu depăşi capacitatea de procesesare a partenerului) şi cwnd-ul curent (pentru a

nu depăşi limita impusă de capacitatea reţelei)

3 la apariţia congestiei sstresh este setat la jumătatea valorii ferestrei curente (minimul

dintre fereastra anunţată de partener şi cwnd icircnsă cel puţin dimensiunea corespunzătoare

pentru două segmente) dacă congestia a fost detectată prin expirarea unui timer de

timeout atunci cwnd este iniţializat cu dimensiunea unui segment

4 la primirea unei confirmări incrementarea se face icircn două moduri icircn funcţie de relaţie icircn

care se află cwnd şi sstresh

1 dacă cwnd e mai mic sau egal cu sstresh se face incrementarea exponenţială

caracteristică slow start-ului (care de fapt nu e deloc slow icircn cazul de faţă)

2 dacă cwnd e mai mare ca sstresh atunci se face o incrementare cu dimensiunea

unui segment

Fast Retransmission Fast Recovery

După cum am văzut un receptor care primeşte segmente out-of-order va trimite transmiţătorului

confirmări duplicate Algoritmul denumit ``fast retransmission recomandă următoarele două

comportamenet

1 un receptor care detectează segmente out-of order trebuie să nu icircntacircrzie trimiterea de

confirmări (după cum am văzut icircn general confimările sunt icircntacircrziate micşora numărul de

pachete fără date care sunt transferate)

2 un transmiţător care care primeşte mai mult de trei confirmări duplicate trebuie să

retrimită segmentul indicat ca fiind neprimit de confirmările icircn cauză fără a aştepta

expirarea timer-ul de timeout

Algoritmul de ``fast recovery icircncearcă să optimizeze şi mai mult comportamentul

transmiţătorului care detectează un număr de trei sau mai multe confimări duplicate Mai exact el

recomandă trecerea la actualizarea liniară a ferestrei (congestion avoidance) Acest tip de

comportament se poate justifica prin următorul raţionament deoarece icircncă mai sunt transferate

date icircntre cei doi parteneri (şi acest lucru se icircntacircmplă sigur de vreme ce sosesc confirmări

duplicate icircn cazul acesta) icircnseamnă că transferul nu este afectat de o congestie severă şi prin

urmare trecerea la slow start nu e (icircncă) necesară (slow start-ul eliberează aproape complet

canalul deoarece cwnd este resetat la dimensiunea unui singur segment)

Cei doi algoritmi pot fi implementaţi icircn felul următor

1 cacircnd se detectează trei confirmări consecutive identice se setează sstresh la jumătate din

valoarea cwnd se retransmite segmentul care s-a pierdut şi se setează cwnd la valoarea

egală cu sstresh plus dimensiunea a trei segmente (acest lucru va face ca algoritmul de

incrementare a cwnd să treacă la incrementare liniară)

2 la fiecare confirmare duplicată care mai soseşte se incrementează cwnd se incrementează

cu dimensiunea unui segment

3 cacircnd icircncetează primirea de confirmări duplicate (segmentul retrimis a ajuns cu bine la

receptor şi s-a trimis o confirmare care acoperă segmentul care se pierduse iniţial) cwnd

este setat la valoarea sstresh

Sindromul ``Silly Window

Protocoalele bazate pe fereastră glisantă (cum este şi TCP-ul) pot să ajungă icircn situaţia deloc

fericită de trimite un număr mare de segmente mici icircn loc de segmente de dimensiune maximă

Acest tip de comportament este cunoscut sub numele de sindromul ``silly window

O modalitate prin care TCP-ul poate să cadă victimă acestui tip de comportament este

deschiderea de ferestre cu dimensiune foarte mică O altă situaţia nefericită este cea icircn care un

transmiţător este ``lacom şi trimite date indiferent de cacirct de mică este fereastra (după cum vom

vedea imediat uneori are sens şi un astfel de comportament) Algoritmul de evitare a acestor

neajunsuri este următorul

1 un receptor nu trebuie să anunţe deschideri de ferestre mici Mai exact nu se recomandă

anunţarea unei incrementări a ferestrei mai mică decacirct dimensiunea unui segment (MSS)

sau jumătate din buffer-ul aflat la dispoziţia receptorului oricare din ele e mai mică

2 un transmiţător va trimite date doar icircn următoarele cazuri

1 se poate trimite un segment icircntreg

2 se poate trimite jumătate din dimensiunea celei mai mari ferestre pe care

partenerul a publicat-o pacircnă acum

3 toate datele trimise pacircnă acum au fost confirmate sau algoritmul Nagle este

dezactivat şi se trimit toate datele care sunt icircn buffer-ul de trimitere

Cacircteva justificări cazul 2b tratează cazul icircn care partenerul anunţă ferestre mai mici decacirct

dimensiunea unui segment iar cazul 2c impune condiţiile respectării algoritmului Nagle după

cum se vede dacă algoritmul Nagle este activ şi s-au acumulat destul date mai exact cacirct

dimensiunea unui segment el va fi trimis chiar dacă există segmente neconfirmate Pentru

implementarea comportamentului impus de 2b un transmiţător trebuie să ţină evidenţa celei mai

mari ferestre pe care partenerul a anunţat-o Ţinacircnd seama că dimensiunea acestor buffer-e nu se

modifică acest mod de a icircncerca determinarea lor este suficient

O altă problemă legată tot de ferestre este cazul icircnchiderii acesteia Un mod icircn care s-ar putea

anunţa redeschiderea este trimiterea de către receptor a unei confirmări (duplicat) care să anunţe

redeschiderea la o anumită valoare a ferestrei Deoarece acest pachet nu trebuie confirmat icircn mod

special şi s-ar putea să se piardă se poate ajunge icircn situaţia icircn care receptorul a anunţat

redeschiderea ferestrei segmentul s-a pierdut iar transmiţătorul icircncă mai icircl mai aşteaptă pentru a

putea continua transferul Rezolvarea la această problemă s-a făcut prin impunerea unui alt

comportament

1 transmiţătorul va trimite segmente cu dimensiunea datelor de un octet prin care sondează

deschiderea ferestrei intervalul la care se sondează redeschiderea ferestrei se dublează

(exponenţial backoff) icircn RFC 793 dimensiunea maximă recomandată este de 2 minute

icircnsă icircn RFC 1122 se specifică că maximul este acelaşi cu cel din cazul retransmisiei (240

secunde)

2 receptorul trebuie să refuze aceste pachete răspunzacircnd cu segmente de confirmare care

indică neprimirea octetului respectiv

Observaţie timer-ul special necesar pentru implementare la transmiţător a comportamentului de mai sus este cunoscut sub numele de ``TCP Persistent Timer Numele este justificat de faptul că sondarea deschiderii se va face pacircnă cacircnd fie fereastra se deschide fie conexiunea se icircntrerupe TCP Keepalive Timer

Un lucru interesant despre TCP este faptul că dacă nivelele superioare nu comunică nimic icircntre

ele pentru o perioadă lungă 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 icircn care au trecut cu succes de faza stabilirii legăturii Dacă nivelurile

inferioare (reţeaIP fizic) devin temporar indisponibile cacirct tip cei doi nu vor să comunice atunci

acest lucru nu va perturba icircn nici un fel activitatea şi acest lucru este acceptabil Problemele

icircncep să apară icircn momentul icircn care cei doi doresc să comunice şi nivelele inferioare nu mai

permit acest lucru Evident că cel care va dori să comunice ceva va detecta icircntreruperea legăturii

şi va icircnchide conexiunea Ce se icircntacircmplă icircnsă dacă celălalt capăt nu are nimic de comunicat (de

exemplu este un server care oferă anumite servicii) Pentru el legătura va fi icircn continuare activă

şi icircn general anumite resurse vor fi rezervate pentru aceasta Rezolvarea acestei situaţii este dată

de introducerea unei mecanism de sondare a stării legăturii pe baza unui timer (TCP Keepalive

Timer) care se declanşează din două icircn două ore La fiecare expirare a timer-ului se trimite un

segment fără date care confirmă datele primite pacircnă atunci Răspunsul care trebuie primit este tot

un segment fără date care confirmă datele primite de partener (practic o re-publicare a stării celor

doi parteneri) Dacă răspunsul nu este primit timp de 75 secunde atunci segmentul va fi retrimis

Dacă după 10 astfel de icircncercări tot nu s-a primit nici un răspuns atunci conexiunea se va

considera terminată şi se va anunţa nivelul superior asupra acestui lucru

Observaţii

dacă o staţie primeşte segmente de keepalive despre conexiuni care nu mai sunt active

(de exemplu a fost resetat) atunci va răspunde cu segmente de reset (acesta e un procedeu

standard)

RFC 1122 specifică că facilitatea de keepalive trebuie activată icircn mod explicit

3 Studii de caz

Subsections

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

1 Fragmentarea pachetelor UDP

Deoarece UDP-ul este un serviciu fără conexiune toate datele pe care le primeşte de la nivelul

superior sunt icircncapsulate icircntr-o singură datagramă UDP care apoi va forma un pachet IP Dacă

pachetul IP astfel obţinut este prea mare atunci mecanismele IP de fragmentare icircl vor sparge icircn

bucăţi Exemplul următor icircncearcă să studieze exact acest fenomen

Pe maşina athos rulează un server de UDP pe portul 50007 Pe o altă maşină frodo aflată icircn

reţeaua locală este rulat un client care poate fi configurat să trimită un pachet UDP de o anumită

lungime Pentru a putea observa ce se icircntacircmplă pe athos este rulat tcpdump

Deoarece MTU-ul pentru o reţea Ethernet este icircn general 1500 şi antetul IP plus cel UDP ocupă

20 + 8 = 28 octeţi o datagramă UDP de dimensiune 1472 ar trebui sa fie trimisă nefragmentată

Pentru siguranţă folosind clientul de pe athos s-a trimis mai icircntacirci o datagramă UDP cu 1471

octeţi de date şi apoi icircncă una cu 1472 Pentru ambele tcpdump a indicat trimiterea lor fără

fragmentare

182556721144 frodonoi33274 gt athosnoi50007 udp 1471 (DF) (ttl 64 id

51481 len 1499)

182559846764 frodonoi33274 gt athosnoi50007 udp 1472 (DF) (ttl 64 id

51793 len 1500)

La o dimensiune de 1473 ar trebui ca trimiterea să genereze două pachete IP unul care să

conţină primii antetul UDP plus primii 1472 octeţi de date şi icircncă un pachet IP care conţine un

singur octet Iată ce indică tcpdump-ul

182605705813 frodonoi gt athosnoi udp (frag 3627411480) (ttl 64 len

21)

182605706116 frodonoi33274 gt athosnoi50007 udp 1473 (frag

3627414800+) (ttl 64 len 1500)

Intr-adevăr au fost generate două pachete IP

primul conţine doar un singur octet de date şi reprezintă ultimul fragment (bitul de more

fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest

lucru) care a fost spartă icircn bucăţi deplasamentul octetului primit in datagrama originală

este 1480

al doilea pachet este primul fragment din datagrama UDP şi conţine antetul UDP (din

cauza asta datele efective ocupă doar 1480 octeţi) deplasamentul este 0 şi bitul de more

fragments este setat (acest lucru este indicat de semnul ``+ de după deplasament)

După cum se poate observa ambele pachete poartă acelaşi număr de identificare (36274) Acest

lucru icircmpreună cu informaţiile date de flag-ul more fragments permite reconstrucţia la

destinaţie a datagramei UDP originale O problemă a acestui mod de fragmentare e că icircn cazul

pierderii unui fragment icircntreaga datagramă va fi compromisă şi va trebui retrimisă icircn icircntregime

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 19: udp tcp

Algoritmul de ``fast recovery icircncearcă să optimizeze şi mai mult comportamentul

transmiţătorului care detectează un număr de trei sau mai multe confimări duplicate Mai exact el

recomandă trecerea la actualizarea liniară a ferestrei (congestion avoidance) Acest tip de

comportament se poate justifica prin următorul raţionament deoarece icircncă mai sunt transferate

date icircntre cei doi parteneri (şi acest lucru se icircntacircmplă sigur de vreme ce sosesc confirmări

duplicate icircn cazul acesta) icircnseamnă că transferul nu este afectat de o congestie severă şi prin

urmare trecerea la slow start nu e (icircncă) necesară (slow start-ul eliberează aproape complet

canalul deoarece cwnd este resetat la dimensiunea unui singur segment)

Cei doi algoritmi pot fi implementaţi icircn felul următor

1 cacircnd se detectează trei confirmări consecutive identice se setează sstresh la jumătate din

valoarea cwnd se retransmite segmentul care s-a pierdut şi se setează cwnd la valoarea

egală cu sstresh plus dimensiunea a trei segmente (acest lucru va face ca algoritmul de

incrementare a cwnd să treacă la incrementare liniară)

2 la fiecare confirmare duplicată care mai soseşte se incrementează cwnd se incrementează

cu dimensiunea unui segment

3 cacircnd icircncetează primirea de confirmări duplicate (segmentul retrimis a ajuns cu bine la

receptor şi s-a trimis o confirmare care acoperă segmentul care se pierduse iniţial) cwnd

este setat la valoarea sstresh

Sindromul ``Silly Window

Protocoalele bazate pe fereastră glisantă (cum este şi TCP-ul) pot să ajungă icircn situaţia deloc

fericită de trimite un număr mare de segmente mici icircn loc de segmente de dimensiune maximă

Acest tip de comportament este cunoscut sub numele de sindromul ``silly window

O modalitate prin care TCP-ul poate să cadă victimă acestui tip de comportament este

deschiderea de ferestre cu dimensiune foarte mică O altă situaţia nefericită este cea icircn care un

transmiţător este ``lacom şi trimite date indiferent de cacirct de mică este fereastra (după cum vom

vedea imediat uneori are sens şi un astfel de comportament) Algoritmul de evitare a acestor

neajunsuri este următorul

1 un receptor nu trebuie să anunţe deschideri de ferestre mici Mai exact nu se recomandă

anunţarea unei incrementări a ferestrei mai mică decacirct dimensiunea unui segment (MSS)

sau jumătate din buffer-ul aflat la dispoziţia receptorului oricare din ele e mai mică

2 un transmiţător va trimite date doar icircn următoarele cazuri

1 se poate trimite un segment icircntreg

2 se poate trimite jumătate din dimensiunea celei mai mari ferestre pe care

partenerul a publicat-o pacircnă acum

3 toate datele trimise pacircnă acum au fost confirmate sau algoritmul Nagle este

dezactivat şi se trimit toate datele care sunt icircn buffer-ul de trimitere

Cacircteva justificări cazul 2b tratează cazul icircn care partenerul anunţă ferestre mai mici decacirct

dimensiunea unui segment iar cazul 2c impune condiţiile respectării algoritmului Nagle după

cum se vede dacă algoritmul Nagle este activ şi s-au acumulat destul date mai exact cacirct

dimensiunea unui segment el va fi trimis chiar dacă există segmente neconfirmate Pentru

implementarea comportamentului impus de 2b un transmiţător trebuie să ţină evidenţa celei mai

mari ferestre pe care partenerul a anunţat-o Ţinacircnd seama că dimensiunea acestor buffer-e nu se

modifică acest mod de a icircncerca determinarea lor este suficient

O altă problemă legată tot de ferestre este cazul icircnchiderii acesteia Un mod icircn care s-ar putea

anunţa redeschiderea este trimiterea de către receptor a unei confirmări (duplicat) care să anunţe

redeschiderea la o anumită valoare a ferestrei Deoarece acest pachet nu trebuie confirmat icircn mod

special şi s-ar putea să se piardă se poate ajunge icircn situaţia icircn care receptorul a anunţat

redeschiderea ferestrei segmentul s-a pierdut iar transmiţătorul icircncă mai icircl mai aşteaptă pentru a

putea continua transferul Rezolvarea la această problemă s-a făcut prin impunerea unui alt

comportament

1 transmiţătorul va trimite segmente cu dimensiunea datelor de un octet prin care sondează

deschiderea ferestrei intervalul la care se sondează redeschiderea ferestrei se dublează

(exponenţial backoff) icircn RFC 793 dimensiunea maximă recomandată este de 2 minute

icircnsă icircn RFC 1122 se specifică că maximul este acelaşi cu cel din cazul retransmisiei (240

secunde)

2 receptorul trebuie să refuze aceste pachete răspunzacircnd cu segmente de confirmare care

indică neprimirea octetului respectiv

Observaţie timer-ul special necesar pentru implementare la transmiţător a comportamentului de mai sus este cunoscut sub numele de ``TCP Persistent Timer Numele este justificat de faptul că sondarea deschiderii se va face pacircnă cacircnd fie fereastra se deschide fie conexiunea se icircntrerupe TCP Keepalive Timer

Un lucru interesant despre TCP este faptul că dacă nivelele superioare nu comunică nimic icircntre

ele pentru o perioadă lungă 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 icircn care au trecut cu succes de faza stabilirii legăturii Dacă nivelurile

inferioare (reţeaIP fizic) devin temporar indisponibile cacirct tip cei doi nu vor să comunice atunci

acest lucru nu va perturba icircn nici un fel activitatea şi acest lucru este acceptabil Problemele

icircncep să apară icircn momentul icircn care cei doi doresc să comunice şi nivelele inferioare nu mai

permit acest lucru Evident că cel care va dori să comunice ceva va detecta icircntreruperea legăturii

şi va icircnchide conexiunea Ce se icircntacircmplă icircnsă dacă celălalt capăt nu are nimic de comunicat (de

exemplu este un server care oferă anumite servicii) Pentru el legătura va fi icircn continuare activă

şi icircn general anumite resurse vor fi rezervate pentru aceasta Rezolvarea acestei situaţii este dată

de introducerea unei mecanism de sondare a stării legăturii pe baza unui timer (TCP Keepalive

Timer) care se declanşează din două icircn două ore La fiecare expirare a timer-ului se trimite un

segment fără date care confirmă datele primite pacircnă atunci Răspunsul care trebuie primit este tot

un segment fără date care confirmă datele primite de partener (practic o re-publicare a stării celor

doi parteneri) Dacă răspunsul nu este primit timp de 75 secunde atunci segmentul va fi retrimis

Dacă după 10 astfel de icircncercări tot nu s-a primit nici un răspuns atunci conexiunea se va

considera terminată şi se va anunţa nivelul superior asupra acestui lucru

Observaţii

dacă o staţie primeşte segmente de keepalive despre conexiuni care nu mai sunt active

(de exemplu a fost resetat) atunci va răspunde cu segmente de reset (acesta e un procedeu

standard)

RFC 1122 specifică că facilitatea de keepalive trebuie activată icircn mod explicit

3 Studii de caz

Subsections

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

1 Fragmentarea pachetelor UDP

Deoarece UDP-ul este un serviciu fără conexiune toate datele pe care le primeşte de la nivelul

superior sunt icircncapsulate icircntr-o singură datagramă UDP care apoi va forma un pachet IP Dacă

pachetul IP astfel obţinut este prea mare atunci mecanismele IP de fragmentare icircl vor sparge icircn

bucăţi Exemplul următor icircncearcă să studieze exact acest fenomen

Pe maşina athos rulează un server de UDP pe portul 50007 Pe o altă maşină frodo aflată icircn

reţeaua locală este rulat un client care poate fi configurat să trimită un pachet UDP de o anumită

lungime Pentru a putea observa ce se icircntacircmplă pe athos este rulat tcpdump

Deoarece MTU-ul pentru o reţea Ethernet este icircn general 1500 şi antetul IP plus cel UDP ocupă

20 + 8 = 28 octeţi o datagramă UDP de dimensiune 1472 ar trebui sa fie trimisă nefragmentată

Pentru siguranţă folosind clientul de pe athos s-a trimis mai icircntacirci o datagramă UDP cu 1471

octeţi de date şi apoi icircncă una cu 1472 Pentru ambele tcpdump a indicat trimiterea lor fără

fragmentare

182556721144 frodonoi33274 gt athosnoi50007 udp 1471 (DF) (ttl 64 id

51481 len 1499)

182559846764 frodonoi33274 gt athosnoi50007 udp 1472 (DF) (ttl 64 id

51793 len 1500)

La o dimensiune de 1473 ar trebui ca trimiterea să genereze două pachete IP unul care să

conţină primii antetul UDP plus primii 1472 octeţi de date şi icircncă un pachet IP care conţine un

singur octet Iată ce indică tcpdump-ul

182605705813 frodonoi gt athosnoi udp (frag 3627411480) (ttl 64 len

21)

182605706116 frodonoi33274 gt athosnoi50007 udp 1473 (frag

3627414800+) (ttl 64 len 1500)

Intr-adevăr au fost generate două pachete IP

primul conţine doar un singur octet de date şi reprezintă ultimul fragment (bitul de more

fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest

lucru) care a fost spartă icircn bucăţi deplasamentul octetului primit in datagrama originală

este 1480

al doilea pachet este primul fragment din datagrama UDP şi conţine antetul UDP (din

cauza asta datele efective ocupă doar 1480 octeţi) deplasamentul este 0 şi bitul de more

fragments este setat (acest lucru este indicat de semnul ``+ de după deplasament)

După cum se poate observa ambele pachete poartă acelaşi număr de identificare (36274) Acest

lucru icircmpreună cu informaţiile date de flag-ul more fragments permite reconstrucţia la

destinaţie a datagramei UDP originale O problemă a acestui mod de fragmentare e că icircn cazul

pierderii unui fragment icircntreaga datagramă va fi compromisă şi va trebui retrimisă icircn icircntregime

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 20: udp tcp

O altă problemă legată tot de ferestre este cazul icircnchiderii acesteia Un mod icircn care s-ar putea

anunţa redeschiderea este trimiterea de către receptor a unei confirmări (duplicat) care să anunţe

redeschiderea la o anumită valoare a ferestrei Deoarece acest pachet nu trebuie confirmat icircn mod

special şi s-ar putea să se piardă se poate ajunge icircn situaţia icircn care receptorul a anunţat

redeschiderea ferestrei segmentul s-a pierdut iar transmiţătorul icircncă mai icircl mai aşteaptă pentru a

putea continua transferul Rezolvarea la această problemă s-a făcut prin impunerea unui alt

comportament

1 transmiţătorul va trimite segmente cu dimensiunea datelor de un octet prin care sondează

deschiderea ferestrei intervalul la care se sondează redeschiderea ferestrei se dublează

(exponenţial backoff) icircn RFC 793 dimensiunea maximă recomandată este de 2 minute

icircnsă icircn RFC 1122 se specifică că maximul este acelaşi cu cel din cazul retransmisiei (240

secunde)

2 receptorul trebuie să refuze aceste pachete răspunzacircnd cu segmente de confirmare care

indică neprimirea octetului respectiv

Observaţie timer-ul special necesar pentru implementare la transmiţător a comportamentului de mai sus este cunoscut sub numele de ``TCP Persistent Timer Numele este justificat de faptul că sondarea deschiderii se va face pacircnă cacircnd fie fereastra se deschide fie conexiunea se icircntrerupe TCP Keepalive Timer

Un lucru interesant despre TCP este faptul că dacă nivelele superioare nu comunică nimic icircntre

ele pentru o perioadă lungă 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 icircn care au trecut cu succes de faza stabilirii legăturii Dacă nivelurile

inferioare (reţeaIP fizic) devin temporar indisponibile cacirct tip cei doi nu vor să comunice atunci

acest lucru nu va perturba icircn nici un fel activitatea şi acest lucru este acceptabil Problemele

icircncep să apară icircn momentul icircn care cei doi doresc să comunice şi nivelele inferioare nu mai

permit acest lucru Evident că cel care va dori să comunice ceva va detecta icircntreruperea legăturii

şi va icircnchide conexiunea Ce se icircntacircmplă icircnsă dacă celălalt capăt nu are nimic de comunicat (de

exemplu este un server care oferă anumite servicii) Pentru el legătura va fi icircn continuare activă

şi icircn general anumite resurse vor fi rezervate pentru aceasta Rezolvarea acestei situaţii este dată

de introducerea unei mecanism de sondare a stării legăturii pe baza unui timer (TCP Keepalive

Timer) care se declanşează din două icircn două ore La fiecare expirare a timer-ului se trimite un

segment fără date care confirmă datele primite pacircnă atunci Răspunsul care trebuie primit este tot

un segment fără date care confirmă datele primite de partener (practic o re-publicare a stării celor

doi parteneri) Dacă răspunsul nu este primit timp de 75 secunde atunci segmentul va fi retrimis

Dacă după 10 astfel de icircncercări tot nu s-a primit nici un răspuns atunci conexiunea se va

considera terminată şi se va anunţa nivelul superior asupra acestui lucru

Observaţii

dacă o staţie primeşte segmente de keepalive despre conexiuni care nu mai sunt active

(de exemplu a fost resetat) atunci va răspunde cu segmente de reset (acesta e un procedeu

standard)

RFC 1122 specifică că facilitatea de keepalive trebuie activată icircn mod explicit

3 Studii de caz

Subsections

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

1 Fragmentarea pachetelor UDP

Deoarece UDP-ul este un serviciu fără conexiune toate datele pe care le primeşte de la nivelul

superior sunt icircncapsulate icircntr-o singură datagramă UDP care apoi va forma un pachet IP Dacă

pachetul IP astfel obţinut este prea mare atunci mecanismele IP de fragmentare icircl vor sparge icircn

bucăţi Exemplul următor icircncearcă să studieze exact acest fenomen

Pe maşina athos rulează un server de UDP pe portul 50007 Pe o altă maşină frodo aflată icircn

reţeaua locală este rulat un client care poate fi configurat să trimită un pachet UDP de o anumită

lungime Pentru a putea observa ce se icircntacircmplă pe athos este rulat tcpdump

Deoarece MTU-ul pentru o reţea Ethernet este icircn general 1500 şi antetul IP plus cel UDP ocupă

20 + 8 = 28 octeţi o datagramă UDP de dimensiune 1472 ar trebui sa fie trimisă nefragmentată

Pentru siguranţă folosind clientul de pe athos s-a trimis mai icircntacirci o datagramă UDP cu 1471

octeţi de date şi apoi icircncă una cu 1472 Pentru ambele tcpdump a indicat trimiterea lor fără

fragmentare

182556721144 frodonoi33274 gt athosnoi50007 udp 1471 (DF) (ttl 64 id

51481 len 1499)

182559846764 frodonoi33274 gt athosnoi50007 udp 1472 (DF) (ttl 64 id

51793 len 1500)

La o dimensiune de 1473 ar trebui ca trimiterea să genereze două pachete IP unul care să

conţină primii antetul UDP plus primii 1472 octeţi de date şi icircncă un pachet IP care conţine un

singur octet Iată ce indică tcpdump-ul

182605705813 frodonoi gt athosnoi udp (frag 3627411480) (ttl 64 len

21)

182605706116 frodonoi33274 gt athosnoi50007 udp 1473 (frag

3627414800+) (ttl 64 len 1500)

Intr-adevăr au fost generate două pachete IP

primul conţine doar un singur octet de date şi reprezintă ultimul fragment (bitul de more

fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest

lucru) care a fost spartă icircn bucăţi deplasamentul octetului primit in datagrama originală

este 1480

al doilea pachet este primul fragment din datagrama UDP şi conţine antetul UDP (din

cauza asta datele efective ocupă doar 1480 octeţi) deplasamentul este 0 şi bitul de more

fragments este setat (acest lucru este indicat de semnul ``+ de după deplasament)

După cum se poate observa ambele pachete poartă acelaşi număr de identificare (36274) Acest

lucru icircmpreună cu informaţiile date de flag-ul more fragments permite reconstrucţia la

destinaţie a datagramei UDP originale O problemă a acestui mod de fragmentare e că icircn cazul

pierderii unui fragment icircntreaga datagramă va fi compromisă şi va trebui retrimisă icircn icircntregime

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 21: udp tcp

Subsections

1 Fragmentarea pachetelor UDP

2 Stabilirea şi eliberarea unei conexiuni TCP

3 Transferul de date TCP

1 Fragmentarea pachetelor UDP

Deoarece UDP-ul este un serviciu fără conexiune toate datele pe care le primeşte de la nivelul

superior sunt icircncapsulate icircntr-o singură datagramă UDP care apoi va forma un pachet IP Dacă

pachetul IP astfel obţinut este prea mare atunci mecanismele IP de fragmentare icircl vor sparge icircn

bucăţi Exemplul următor icircncearcă să studieze exact acest fenomen

Pe maşina athos rulează un server de UDP pe portul 50007 Pe o altă maşină frodo aflată icircn

reţeaua locală este rulat un client care poate fi configurat să trimită un pachet UDP de o anumită

lungime Pentru a putea observa ce se icircntacircmplă pe athos este rulat tcpdump

Deoarece MTU-ul pentru o reţea Ethernet este icircn general 1500 şi antetul IP plus cel UDP ocupă

20 + 8 = 28 octeţi o datagramă UDP de dimensiune 1472 ar trebui sa fie trimisă nefragmentată

Pentru siguranţă folosind clientul de pe athos s-a trimis mai icircntacirci o datagramă UDP cu 1471

octeţi de date şi apoi icircncă una cu 1472 Pentru ambele tcpdump a indicat trimiterea lor fără

fragmentare

182556721144 frodonoi33274 gt athosnoi50007 udp 1471 (DF) (ttl 64 id

51481 len 1499)

182559846764 frodonoi33274 gt athosnoi50007 udp 1472 (DF) (ttl 64 id

51793 len 1500)

La o dimensiune de 1473 ar trebui ca trimiterea să genereze două pachete IP unul care să

conţină primii antetul UDP plus primii 1472 octeţi de date şi icircncă un pachet IP care conţine un

singur octet Iată ce indică tcpdump-ul

182605705813 frodonoi gt athosnoi udp (frag 3627411480) (ttl 64 len

21)

182605706116 frodonoi33274 gt athosnoi50007 udp 1473 (frag

3627414800+) (ttl 64 len 1500)

Intr-adevăr au fost generate două pachete IP

primul conţine doar un singur octet de date şi reprezintă ultimul fragment (bitul de more

fragments este resetat) dintr-o datagrama UDP (din antetul IP se poate determina acest

lucru) care a fost spartă icircn bucăţi deplasamentul octetului primit in datagrama originală

este 1480

al doilea pachet este primul fragment din datagrama UDP şi conţine antetul UDP (din

cauza asta datele efective ocupă doar 1480 octeţi) deplasamentul este 0 şi bitul de more

fragments este setat (acest lucru este indicat de semnul ``+ de după deplasament)

După cum se poate observa ambele pachete poartă acelaşi număr de identificare (36274) Acest

lucru icircmpreună cu informaţiile date de flag-ul more fragments permite reconstrucţia la

destinaţie a datagramei UDP originale O problemă a acestui mod de fragmentare e că icircn cazul

pierderii unui fragment icircntreaga datagramă va fi compromisă şi va trebui retrimisă icircn icircntregime

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 22: udp tcp

Ce se va icircntacircmpla dacă vom icircncerca să trimitem un datagrama UDP suficient de mare pentru a

necesita spargerea icircn trei bucăţi Iată mai jos un transfer de 2973 de octeţi

132108251495 frodonoi gt athosnoi udp (frag 2352212960) (ttl 64 len

21)

132108251795 frodonoi gt athosnoi udp (frag 2352214801480+) (ttl 64

len 1500)

132108251935 frodonoi32843 gt athosnoi50007 udp 2953 (frag

2352214800+) (ttl 64 len 1500)

După cum se poate observa trimiterea icircn ordine inversă este o caracteristică a sistemului pe care

am testat O datagramă de dimesiune şi mai mare (16273) confirmă acest lucru

132152266391 frodonoi gt athosnoi udp (frag 23523116280) (ttl 64 len

21)

132152266697 frodonoi gt athosnoi udp (frag 23523148014800+) (ttl 64

len 1500)

132152266843 frodonoi gt athosnoi udp (frag 23523148013320+) (ttl 64

len 1500)

132152266976 frodonoi gt athosnoi udp (frag 23523148011840+) (ttl 64

len 1500)

132152267114 frodonoi gt athosnoi udp (frag 23523148010360+) (ttl 64

len 1500)

132152267253 frodonoi gt athosnoi udp (frag 2352314808880+) (ttl 64

len 1500)

132152267391 frodonoi gt athosnoi udp (frag 2352314807400+) (ttl 64

len 1500)

132152267539 frodonoi gt athosnoi udp (frag 2352314805920+) (ttl 64

len 1500)

132152267678 frodonoi gt athosnoi udp (frag 2352314804440+) (ttl 64

len 1500)

132152267819 frodonoi gt athosnoi udp (frag 2352314802960+) (ttl 64

len 1500)

132152267956 frodonoi gt athosnoi udp (frag 2352314801480+) (ttl 64

len 1500)

132152268096 frodonoi32843 gt athosnoi50007 udp 16273 (frag

2352314800+) (ttl 64 len 1500)

2 Stabilirea şi eliberarea unei conexiuni TCP

Pentru a studia modul de stabilire al unei conexiuni TCP vom rula pe o maşină (frodo) un server

de TCP care va asculta pe portul 50007 va accepta fiecare conexiune primită şi o va icircnchide

imediat Clientul va rula pe o altă maşină (alexandra) şi după stabilirea conexiunii va icircnchide la

racircndul său conexiunea Deşi acest lucru ar trebui să ducă la o icircnchidere simultană icircn realitate

vom vedea că are loc o icircnchidere normală

Iată ce arată un tcpdump rulat pe alexandra

[numbers=left]

224647558868 alexandranoi34437 gt frodonoi50007 SWE

24816418282481641828(0)

win 5840 ltmss 1460sackOKtimestamp 10422756 0nopwscale

0gt (DF)

224647559023 frodonoi50007 gt alexandranoi34437 S

15798022861579802286(0) ack 2481641829

win 5792 ltmss 1460sackOKtimestamp 9639913

10422756nopwscale 0gt (DF)

224647559081 alexandranoi34437 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647559435 frodonoi50007 gt alexandranoi34437 F 11(0) ack 1

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 23: udp tcp

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

224647560243 alexandranoi34437 gt frodonoi50007 F 11(0) ack 2

win 5840 ltnopnoptimestamp 10422756 9639913gt (DF)

224647560332 frodonoi50007 gt alexandranoi34437 ack 2

win 5792 ltnopnoptimestamp 9639913 10422756gt (DF)

Liniile 1-2 reprezintă segmentul de SYN trimis de clientul de pe alexandra Numărul de

secvenţă este 2481641828 dimensiunea datelor efective este 0 flag-ul de ACK nu este setat

dimensiunea ferestrei este de 5840 octeţi (aceasta corespunde spaţiului ocupat de 4 segmente

TCP conţinacircnd fiecare 1460 octeţi de date) dimensiunea maximă a unui segment (MSS) este de

1460 octeţi (această dimensiune este justificată de faptul că icircntr-un frame Ethernet nu se pot

trimite mai mult de 1500 octeţi şi antetul IP + TCP ocupă 40 de octeţi) Alte informaţii pe care

acest prim segment le conţine staţia este capabilă de a lucra cu notificări explicite referitoare la

congestie (prezentă flagurilor WE indică acest lucru W corespunde flag-ului TCP Congestion

Window Reduced iar E ECN-Echo ECN este acronimul de la Explicit Congestion Notification)

cu confirmări selective (sackOK) cu marcaje de timp (timestamp) şi cu scalări de ferestre

(wscale)

Răspunsul (liniile 3-4) trimis de server-ul (frodo) confirmă primirea segmentului (ack

2481641829) de deschidere de conexiune şi işi publică şi el informaţiile legate de fereastră

MSS timestamp şi scalări ale dimensiunii ferestrei Icircn plus faptul că flag-ul ECN-Echo nu este

setat (E ar fi trebuit să apară lacircngă S) indică faptul că sistemul nu este capabil de ECN

Liniile 5-6 reprezintă ultimul pas din secvenţa de iniţializare confirmarea de către client a

segmentului trimis de server Se poate observa că de aici icircncolo tcpdump-ul afişează valori

relative pentru numere de secvenţă şi cele de confirmare

Mai departe (liniile 7-8) frodo cere icircnchiderea conxiunii (este setat flag-ul de FYN) prin

trimiterea unui segment care nu conţine date dar are un nou număr de secvenţă (e nevoie de aşa

ceva pentru ca partenerul să poată confirma primirea acestui segment) alexandra răspunde

(liniile 9-10) cu un segment care confirmă primirea segmentului de la frodo şi anunţă terminarea

conexiunii şi din capătul lui După ce alexandra confirmă primirea segmentului cele ambele

staţii consideră dialogul icircncheiat

3 Transferul de date TCP

Icircn condiţii similare cu experimentul precedent vom icircncerca să observăm modul icircn care are loc un

transfer simplu de date Serverul va rula pe frodo şi se va comporta ca un reflector după

stabilirea conexiunii aşteaptă primirea unor date pe care apoi le trimite icircnapoi la destinaţie

Clientul va rula pe alexandra şi după stabiliea conexiunii va trimite 8 octeţi de date va aştepta

răspunsul şi apoi va icircnchide conexiunea

Un tcpdump rulat pe alexandra arată următoarele

[numbers=left]

210947449182 alexandranoi35455 gt frodonoi50007 SWE

35311388503531138850(0)

win 5840 ltmss 1460sackOKtimestamp 14016045 0nopwscale

0gt (DF)

210947449326 frodonoi50007 gt alexandranoi35455 S

28332841982833284198(0) ack 3531138851

win 5792 ltmss 1460sackOKtimestamp 13950430

14016045nopwscale 0gt (DF)

210947449374 alexandranoi35455 gt frodonoi50007 ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000
Page 24: udp tcp

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947449924 alexandranoi35455 gt frodonoi50007 P 19(8) ack 1

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450025 frodonoi50007 gt alexandranoi35455 ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450145 frodonoi50007 gt alexandranoi35455 P 19(8) ack 9

win 5792 ltnopnoptimestamp 13950430 14016045gt (DF)

210947450161 alexandranoi35455 gt frodonoi50007 ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450487 alexandranoi35455 gt frodonoi50007 F 99(0) ack 9

win 5840 ltnopnoptimestamp 14016045 13950430gt (DF)

210947450660 frodonoi50007 gt alexandranoi35455 F 99(0) ack 10

win 5792 ltnopnoptimestamp 13950431 14016045gt (DF)

210947450691 alexandranoi35455 gt frodonoi50007 ack 10

win 5840 ltnopnoptimestamp 14016045 13950431gt (DF)

Primele trei segmente (liniile 1-6) reprezintă o deshidere identică cu cea pe care am studiat-o icircn

cazul precedent Segmentul care apare pe liniile 7-8 reprezintă cei 8 octeţi de date care se doreau

transferaţi Deoarece segmentul conţine toate datele flagul de PUSH este activat După ce datele

au fost recepţionate la server acesta generează un segment fără date (liniile 9-10) şi apoi le

trimite icircnapoi (liniile 10-11) Clientul care le primeşte răspunde cu un segment de confirmare

(liniile 13-14) Mai departe urmează o icircnchidere similară cu cea din exemplu precedent(liniile

15-20)

O observaţie care se poate face pe baza afişării furnizate de tcpdump e că mecanismul de

icircntacircrziere a confirmărilor nu a fost activ Dacă ar fi fost activ atunci confirmarea din segmentul

de pe liniile 13-14 ar fi trebui să facă parte din segmentul de date care urmează imediat (liniile

15-16) O posibilă explicaţie e că frodo e icircncă icircn porţiunea de slow start icircn care nici o

confirmare nu e icircntărziată pentru a deschide cacirct mai repede fereastra de congestie

  • CHILD_LINKS
  • tex2html14
  • tex2html15
  • tex2html16
  • tex2html17
  • tex2html18
  • tex2html19
  • tex2html20
  • tex2html21
  • tex2html22
  • tex2html23
  • tex2html24
  • tex2html25
  • tex2html26
  • tex2html27
  • tex2html28
  • tex2html29
  • tex2html30
  • tex2html31
  • tex2html32
  • tex2html33
  • tex2html34
  • tex2html35
  • tex2html36
  • tex2html37
  • tex2html38
  • tex2html39
  • tex2html40
  • tex2html41
  • SECTION00100000000000000000
  • tex2html50
  • tex2html51
  • tex2html52
  • tex2html53
  • tex2html54
  • tex2html55
  • tex2html56
  • tex2html57
  • tex2html58
  • tex2html59
  • tex2html60
  • tex2html61
  • tex2html62
  • tex2html63
  • tex2html64
  • SECTION00700000000000000000
  • tex2html77
  • tex2html78
  • tex2html79
  • tex2html80
  • tex2html81
  • tex2html82
  • tex2html83
  • tex2html84
  • tex2html85
  • tex2html86
  • tex2html87
  • tex2html88
  • tex2html89
  • tex2html90
  • tex2html91
  • tex2html92
  • tex2html93
  • tex2html94
  • tex2html95
  • tex2html96
  • tex2html97
  • tex2html98
  • tex2html99
  • tex2html100
  • tex2html101
  • tex2html102
  • tex2html103
  • SECTION00710000000000000000
  • tex2html116
  • tex2html117
  • SECTION00711000000000000000
  • tex2html1
  • foot142
  • SECTION00712000000000000000
  • figudp-segment
  • 154
  • SECTION00720000000000000000
  • tex2html152
  • tex2html153
  • tex2html154
  • tex2html155
  • tex2html156
  • tex2html157
  • tex2html158
  • tex2html159
  • tex2html160
  • tex2html161
  • tex2html162
  • tex2html163
  • tex2html164
  • tex2html165
  • tex2html166
  • tex2html167
  • tex2html168
  • tex2html169
  • tex2html170
  • SECTION00721000000000000000
  • SECTION00722000000000000000
  • figtcp_segment
  • 180
  • figtcp_options
  • 415
  • SECTION00723000000000000000
  • tex2html207
  • tex2html208
  • tex2html209
  • tex2html210
  • tex2html211
  • tex2html212
  • SECTION00723100000000000000
  • tex2html225
  • SECTION00723110000000000000
  • SECTION00723200000000000000
  • tex2html248
  • tex2html249
  • SECTION00723210000000000000
  • SECTION00723220000000000000
  • SECTION00723300000000000000
  • 417
  • figTCPDiagram
  • 258
  • SECTION00724000000000000000
  • tex2html292
  • tex2html293
  • tex2html294
  • tex2html295
  • tex2html296
  • tex2html297
  • tex2html298
  • tex2html299
  • tex2html300
  • SECTION00724100000000000000
  • tex2html7
  • foot264
  • SECTION00724200000000000000
  • tex2html8
  • foot266
  • SECTION00724300000000000000
  • SECTION00724400000000000000
  • tex2html9
  • foot274
  • SECTION00724500000000000000
  • SECTION00724600000000000000
  • SECTION00724700000000000000
  • SECTION00724800000000000000
  • silly2
  • silly3
  • SECTION00724900000000000000
  • SECTION00730000000000000000
  • tex2html417
  • tex2html418
  • tex2html419
  • SECTION00731000000000000000
  • SECTION00732000000000000000
  • SECTION00733000000000000000

Recommended