Principi di trasferimento affidabile Il livello rete è inaffidabile: Presenza di errori Perdita e duplicazione di pacchetti Ordine dei pacchetti non garantito In caso di errori è necessario: Rilevare e/o identificare gli errori Correggere gli errori oppure notificare al mittente Chiedere la ritrasmissione Tutto questo considerando le risorse di rete e le risorse del destinatario Principi di trasferimento affidabile Servizio offerto Implementazione del servizio e caratteristiche del canale inaffidabile determinano la complessità del protocollo di trasferimento affidabile (rdt: reliable data transfer, udt: unreliable data transfer) 1
Trasferimento affidabile rdt_send(): chiamata dall alto (da app.). I dati vengono passati per la consegna al ricevente deliver_data(): chiamata da rdt per consegnare di dati al livello superiore send side receive side udt_send(): chiamata da rdt per trasferire pacchetti su un canale inaffidabile rdt_rcv(): chiamata quando i pacchetti arrivano su lato ricevente del canale Macchine a stati finiti (FSM) Stato iniziale Evento che causa la transizione di stato Azione conseguente stato 1 evento azione stato 2 o stato successivo è determinato dal prossimo evento 2
rdt1.0: trasferimento affidabile su canale affidabile Canale sottostante affidabile no errori sui bit no perdita di pacchetti FSM per sender e receiver: sender invia dati al canale sottostante receiver legge dati dal canale sottostante call from packet = make_pkt(data) udt_send(packet) call from rdt_rcv(packet) extract (packet,data) sender receiver rdt2.0: canale con errori sui bit Meccanismi: o riconoscimento errori (checksum) o feedback: messaggi di controllo (ACK,NAK) dal receiver al sender acknowledgements (ACK): il receiver conferma la ricezione corretta del pacchetto negative acknowledgements (NAK): il receiver conferma la ricezione del pacchetto con errori o Ritrasmissione del pacchetto al ricevimento di NAK 3
Protocolli ARQ Protocolli di tipo ARQ (Automatic Repeat request) basati su riscontri positivi (ACK), riscontri negativi (NAK) e ritrasmissione. Protocollo stop-and-wait: dopo l invio del pacchetto il sender deve ricevere ACK prima di poter inviare altri dati rdt2.0: FSM sndpkt = make_pkt(data, checksum) call from isack(rcvpkt) sender ACK or NAK isnak(rcvpkt) receiver corrupt(rcvpkt) udt_send(nak) call from notcorrupt(rcvpkt) udt_send(ack) 4
rdt2.0: problema Problema: ACK/NAK con errori Il sender non sa se il receiver ha inviato ACK o NACK Ritrasmette possibili duplicati Gestione dei duplicati: Il sender ritrasmette il pacchetto se ACK/NAK corrotti Il sender aggiunge un numero di sequenza ad ogni pacchetto Il receiver scarta i pacchetti duplicati rdt2.1: sender && isack(rcvpkt) isnak(rcvpkt) ) sndpkt = make_pkt(0, data, checksum) call 0 from ACK or NAK ACK or NAK call 1 from isnak(rcvpkt) ) && isack(rcvpkt) sndpkt = make_pkt(1, data, checksum) 5
rdt2.1: receiver (corrupt(rcvpkt) sndpkt = make_pkt(nak, chksum) not corrupt(rcvpkt) && has_seq1(rcvpkt) sndpkt = make_pkt(ack, chksum) notcorrupt(rcvpkt) && has_seq0(rcvpkt) sndpkt = make_pkt(ack, chksum) 0 from 1 from notcorrupt(rcvpkt) && has_seq1(rcvpkt) sndpkt = make_pkt(ack, chksum) (corrupt(rcvpkt) sndpkt = make_pkt(nak, chksum) not corrupt(rcvpkt) && has_seq0(rcvpkt) sndpkt = make_pkt(ack, chksum) Riscontri positivi e negativi Aggiungendo un campo di riscontro agli ACK, contenente il numero di sequenza del segmento cui l ACK si riferisce, il NAK può essere sostituito da un ACK duplicato, relativo all ultimo segmento ricevuto correttamente 6
rdt2.1 rdt2.2: sender && isack(rcvpkt,1) isack(rcvpkt,0) ) sndpkt = make_pkt(0, data, checksum) call 0 from ACK1 ACK0 call 1 from sndpkt = make_pkt(1, data, checksum) isack(rcvpkt,1) ) && isack(rcvpkt,0) rdt2.1 rdt2.2: receiver (corrupt(rcvpkt) has_seq1(rcvpkt)) notcorrupt(rcvpkt) && has_seq0(rcvpkt) sndpkt = make_pkt(ack0, chksum) 0 from 1 from notcorrupt(rcvpkt) && has_seq1(rcvpkt) sndpkt = make_pkt(ack1, chksum) (corrupt(rcvpkt) has_seq0(rcvpkt)) 7
rdt3.0: canale con errori e perdita di pacchetti Il canale sottostante può anche perdere pacchetti. È necessario meccanismo per rilevare la perdita di pacchetti (dati o ACK) Se il sender non riceve alcuna notifica dal receiver entro un tempo scelto opportunamente, il pacchetto (o l ACK) è andato perso e il sender ritrasmette Come scegliere tale tempo? Il pacchetto potrebbe arrivare con forte ritardo: problema dei duplicati, risolvibile con numeri di sequenza Ritrasmissione basata sul tempo Meccanismo di conto alla rovescia. Il sender deve: avviare il timer dopo la trasmissione di un pacchetto (nuovo o ritrasmesso) interrompere il timer al ricevimento di un ACK rispondere alle interruzioni del timer 8
rdt3.0 sender call 0 from && isack(rcvpkt,1) stop_timer timeout start_timer isack(rcvpkt,0) ) Wait for ACK1 sndpkt = make_pkt(0, data, checksum) start_timer Wait for ACK0 call 1 from sndpkt = make_pkt(1, data, checksum) start_timer isack(rcvpkt,1) ) timeout start_timer && isack(rcvpkt,0) stop_timer rdt3.0: receiver (corrupt(rcvpkt) has_seq1(rcvpkt)) notcorrupt(rcvpkt) && has_seq0(rcvpkt) sndpkt = make_pkt(ack0, chksum) 0 from 1 from notcorrupt(rcvpkt) && has_seq1(rcvpkt) sndpkt = make_pkt(ack1, chksum) (corrupt(rcvpkt) has_seq0(rcvpkt)) Uguale a rdt2.2 9