10 Comments

  1. Frumos articol, putina lume intelege aceste mecanisme.

    As adauga ca o aproximare grosiera este ca pentru un download la viteza X se consuma X/10 pe upload. Daca uploadul este aproape de aceasta valoare (X/10), atunci orice consum suplimentar Y pe upload scade banda disponibila pe download cu 10Y. In acest caz nu prea e convenabil sa faci share (upload) fara limitare de banda.

    Despre problema propusa, daca imi amintesc bine ambele capete ale conexiunii anunta cat pot sa primeasca, si fiecare calculeaza local (fara sa anunte) fereastra de congestie. Daca se pierd packete, emitatorul scade numarul de packete pe care le trimite fara a primi confirmarea. La limita nu trimite urmatorul packet pana nu primeste ack la packetul precedent. In functie de delay-ul (timpul de ping) intre capete, viteza este limitata la MTU/delay. Trimiterea de ack se poate face la fiecare packet, sau serverul poate trimite un singur ACK daca primeste mai multe packete contigue intr-un interval scurt de timp.

    Ar mai fi interesant de discutat despre sincronizarea mai multor conexiuni TCP, cand toate vad ca exista banda libere, apoi toate detecteaza congestia si elibereaza prea multa banda. Apoi despre ACK-uri care vin prea tarziu, dupa ce serverul a re-transmis deja packetul din cauza faptului ca delay-ul a variat mai mult decat estimase trimitatorul.

    Este o lume complexa, unele consecinte nu au fost prevazute nici de catre cei care au gandit TCP-ul. E bine ca exista pasionati care incearca sa ii descopere tainele.

  2. O idee interesanta care iti vine in minte dupa ce citesti acest articol este sa incerci sa aproximezi viteza de transfer (per TCP flow) in functie de RTT (delay). As vrea sa dezvolt un pic ceea ce a spus Mihai in observatia lui legat de limitarea vitezei la MTU/delay. Din cate cunosc eu, aceasta formula este valabila doar la inceput, cand “window size”(= IW sau initial window) se stabileste ca fiind:
    – SMSS (sender’s maximum segment size) calculat in functie de RMSS (receiver’s MSS) obtinut in faza de “SYN handshake
    – MTU-ul descoperit intre sender si receiver in caz ca exista “Path MTU Discovery
    – MTU de pe interfata pe care se trimite pachetul
    – 536 bytes in absenta altei informatii.

    TCP-ul se fereste de congestie si de aceea seteaza o valoare mica pentru window size la inceput. Ulterior aceasta valoare incepe sa creasca insa fiind un camp de 16 biti din header-ul TCP nu poate depasi 65,535 bytes.

    Fac o paranteza ca sa adaug ca se poate folosi “window scale option” pentru a obtine “window size” pe 30 de biti (cum apare si in captura atasata de tine Ionut) dar eu voi lua ca referinta cei 16 biti. Conexiunile de mare viteza folosesc toate “scale option” deci un “window size” mai mare de 65,535 este frecvent in zilele noastre.

    Asadar window size incepe sa creasca incepand cu MSS/MTU sau 536 bytes dar nu poate depasi 65,535 de bytes. Viteza calculata ca fiind window size/RTT creste si ea de la MTU(bytes)/RTT cum a specificat Mihai pana la 65,535(bytes)/RTT. Notiunea de echilibru in TCP este des intalnita pentru ca tot timpul se coordoneaza sender-ul, receiver-ul si reteaua asa cum ai descris si tu Ionut.

    Haideti sa luam un exemplu concret: Avem o conexiune de 100 Mbps de la un provider si vrem sa tragem ceva din reteaua lui(un singur flow TCP). RTT este de 2 ms iar TCP-ul negociaza window size la 6000 bytes. In acest caz putem afirma ca nu vom depasi o viteza mai mare de 48 Kbiti / 0.002 sec ~ 24 Mbiti pe un singur flow TCP.

    Interesanta ideea de a posta acest articol despre TCP; ma astept la zeci de comentarii si pareri pentru ca intr-adevar se pot spune foarte multe.

  3. Author

    TCP Window Scale nu este un camp separat in header-ul tcp, campul Options este folosit ca si pentru comunicarea MSS. Initial cand a fost gandita expansiunea pentru Window Size, s-a spus ca noul mecanism de scaling va fi folosit pentru”fat-pipes” sau pentru “Long Fat Networks” 😀
    Doar mesajele SYN/[SYN ACK] contin valoarea Window Scale. Window Scale nu specifica intrinsec o noua valoare a ferestrei de transmisie, ci specifica un factor (de exemplu 3) care ne da puterea lui 2 (acest numar este numit “shift count”) cu care trebuie inmultita valoarea curenta a ferestrei pentru a obtine valoarea noua a fereastrei sau “maximum receive buffer space” (2^3*WindowSize).

    “Maximum receive buffer space” este astfel comunicata catre celalalt capat al unei conexiuni TCP (valoare este folosita pentru “flow control”, pentru incercarea de a folosi la maxim atat “teava”, cat si buffer-ele de receptie a fiecarui capat al conexiunii TCP), insa valoare congestion window (valoare folosita pentru “congestion control”, pentru a nu supra-incarca “teava”) nu este comunicata. Totusi ambele capetele ale conexiunii TCP vor folosi minimul dintre congestion window si window size pentru a determina valoarea maxima de date pe care o vor pune pe teava pana asteapta confirmarea primirii lor.

    Optiunea Window Scaling trebuie suportata de ambele capete ale conexiunii TCP. Initiatorul conexiunii TCP trimite optiunea in mesajul SYN initial si numai in cazul asta primeste ca raspuns, in mesajul [SYN,ACK], optiunea Window Scaling a celuilalt capat.

    Dar ce se inampla apoi? Sesiunea TCP a fost stabilita, Window Size-ul a fost negociat, insa caracteristicile conexiunii se schimba: RTT creste sau conexiunea HSDPA devine GPRS …
    Stiu doua lucruri care se pot intampla:
    – RTT canal upstream creste => “self clocking” va scadea rata de transfer pe canalul downstream;
    – conexiunea incepe sa piarda pachete => sesiunea TCP va trece prin “slow start” sau “fast retransmit”, valoarea congestion window fiind acum luata in calcul si nu valoarea window size.

  4. De acord ca “Window Scale Option” nu e camp separat in headerul TCP, nici nu am spus asta; e doar un shift de biti care permite “window size” sa ajunga de la 16 la 30 de biti (deci “shift count” poate fi maxim 14). Fiind doar o paranteza nu am vrut sa intru in detalii.

  5. Author

    Vreau sa va provoc cu doua noi intrebari:

    1. De ce wireshark spune ca pachetul 3534 este ACK pentru 3533 “This is an ACK to the segment in frame: 3533″ desi este un pachet FTP-DATA?
    2. Ce se intampla cu pachetele ACK din aceasta captura?
    Daca luam exemplul pachetului 3535, “Acknowledgement number” este 2518489, valoare pe care o gasim ca si “Sequence number” pentru pachetul 3523.
    Nu ar fi trebuit ca pachetul ACK sa ceara prin “Acknowledgement number” urmatorul pachet (“Acknowledgement number” = urmatorul “Sequence number”)?

  6. Poate ca tie ti se pare familiar outputul de Wireshark pe care l-ai atasat insa pe mine m-a apucat durerea de cap cand am inceput sa ma uit prin el. E complicat sa analizezi fisiere .txt de mii de linii … o idee ar fi fost sa atasezi un .dump pe care sa-l deschidem si noi cu Wireshark. Cand spui serverul X te referi la ip-ul x.x.x.x din captura ?
    Cred ca raspunsul la intrebarea din post-ul initial se refera la delayed ACK. Dupa cum se mentioneaza in RFC1122, atat timp cat RTT dintre doua segmente nu e mai mare de 200ms se va trimite ACK la al doilea segment. Microsoft tine cont de acest RFC insa acest comportament se poate modifica chiar si pe Windows daca adaugi in registri o intrare de tip TcpAckFrequency mai mare decat 2.

  7. Author

    Da, corect, este vorba despre “Delayed ACK”, uneori atat de util, alteori atat de daunator (a se vedea interactiunea dintre algoritmul Nagle si Delayed ACK). Multumesc pentru raspuns!
    Ai dreptate, este mult mai usor de parcurs un output libpcap, se pate descarca de aici

  8. Nice dispatch and this mail helped me alot in my college assignement. Gratefulness you on your information.

  9. Hello,
    foarte tare aceasta discutia,dar daca se poate sa pasam discutia si catre conexiuni cu banda garantata..ce se intampla in acest caz?

  10. Author

    @kalvin daca garantarea upload/download este bine proportionata, nu poate decat sa te ajute.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.