4. PROTOCOLLI DI TRASPORTO (TRANSPORT PROTOCOLS)
4.1 PROTOCOLLO DI DATAGRAMMA UTENTE -- UDP (USER DATAGRAM PROTOCOL)
4.1.1 INTRODUZIONE (INTRODUCTION)
Il Protocollo di Datagramma Utente (User Datagram Protocol, UDP) [UDP:1] fornisce solo un servizio di trasporto minimo -- consegna di datagrammi non garantita -- e offre alle applicazioni l'accesso diretto al servizio di datagramma del livello IP. UDP è utilizzato da applicazioni che non richiedono il livello di servizio di TCP o che desiderano utilizzare servizi di comunicazione (ad esempio, consegna multicast o broadcast) non disponibili con TCP.
UDP è quasi un protocollo nullo; gli unici servizi che fornisce oltre a IP sono il checksum dei dati e il multiplexing per numero di porta. Pertanto, un programma applicativo eseguito su UDP deve affrontare direttamente i problemi di comunicazione end-to-end che un protocollo orientato alla connessione avrebbe gestito -- ad esempio, ritrasmissione per consegna affidabile, pacchettizzazione e riassemblaggio, controllo di flusso, controllo della congestione, ecc., quando questi sono necessari. L'accoppiamento piuttosto complesso tra IP e TCP si rifletterà nell'accoppiamento tra UDP e molte applicazioni che utilizzano UDP.
4.1.2 PERCORSO DEL PROTOCOLLO (PROTOCOL WALK-THROUGH)
Non ci sono errori noti nella specifica UDP.
4.1.3 PROBLEMI SPECIFICI (SPECIFIC ISSUES)
4.1.3.1 Porte (Ports)
Le porte ben note UDP seguono le stesse regole delle porte ben note TCP; vedere la sezione 4.2.2.1 sotto.
Se un datagramma arriva indirizzato a una porta UDP per la quale non c'è una chiamata LISTEN in sospeso, UDP DOVREBBE inviare un messaggio ICMP Port Unreachable.
4.1.3.2 Opzioni IP (IP Options)
UDP DEVE trasmettere trasparentemente al livello applicativo qualsiasi opzione IP che riceve dal livello IP.
Un'applicazione DEVE essere in grado di specificare le opzioni IP da inviare nei suoi datagrammi UDP, e UDP DEVE trasmettere queste opzioni al livello IP.
DISCUSSIONE (DISCUSSION):
Attualmente, le uniche opzioni che devono passare attraverso UDP sono Source Route, Record Route e Time Stamp. Tuttavia, nuove opzioni potrebbero essere definite in futuro, e UDP non ha bisogno e non dovrebbe fare supposizioni sul formato o sul contenuto delle opzioni che trasmette verso o dall'applicazione; un'eccezione a ciò potrebbe essere un'opzione di sicurezza del livello IP.
Un'applicazione basata su UDP dovrà ottenere un percorso di origine da un datagramma di richiesta e fornire un percorso inverso per inviare la risposta corrispondente.
4.1.3.3 Messaggi ICMP (ICMP Messages)
UDP DEVE trasmettere al livello applicativo tutti i messaggi di errore ICMP che riceve dal livello IP. Concettualmente almeno, questo può essere realizzato con una chiamata verso l'alto alla routine ERROR_REPORT (vedere la sezione 4.2.4.1).
DISCUSSIONE:
Si noti che i messaggi di errore ICMP risultanti dall'invio di un datagramma UDP vengono ricevuti in modo asincrono. Un'applicazione basata su UDP che desider a ricevere messaggi di errore ICMP è responsabile del mantenimento dello stato necessario per demultiplexare questi messaggi quando arrivano; ad esempio, l'applicazione può mantenere un'operazione di ricezione in sospeso a questo scopo. L'applicazione è anche responsabile di evitare confusione dovuta a un messaggio di errore ICMP ritardato risultante da un uso precedente della stessa porta o delle stesse porte.
4.1.3.4 Checksum UDP (UDP Checksums)
Un host DEVE implementare la capacità di generare e validare i checksum UDP. Un'applicazione PUÒ opzionalmente essere in grado di controllare se verrà generato un checksum UDP, ma DEVE essere attivato per impostazione predefinita.
Se viene ricevuto un datagramma UDP con un checksum non zero ma non valido, UDP DEVE scartare silenziosamente il datagramma. Un'applicazione PUÒ opzionalmente essere in grado di controllare se i datagrammi UDP senza checksum debbano essere scartati o trasmessi all'applicazione.
DISCUSSIONE:
Alcune applicazioni che normalmente funzionano solo su reti locali scelgono di disattivare i checksum UDP per motivi di efficienza. Di conseguenza, sono stati segnalati molti casi di errori non rilevati. Le raccomandazioni sull'opportunità di disattivare i checksum UDP sono molto controverse.
IMPLEMENTAZIONE (IMPLEMENTATION):
C'è un errore di implementazione comune nel checksum UDP. A differenza del checksum TCP, il checksum UDP è opzionale; uno zero trasmesso nel campo checksum dell'intestazione UDP indica l'assenza di un checksum. Se il checksum UDP effettivamente calcolato dal mittente è zero, deve essere trasmesso come tutti uno (65535). Il ricevitore non ha bisogno di intraprendere azioni speciali, poiché nell'aritmetica in complemento a uno, zero e 65535 sono equivalenti.
4.1.3.5 Multihoming UDP
Quando viene ricevuto un datagramma UDP, il suo indirizzo di destinazione specifico DEVE essere trasmesso al livello applicativo.
Un'applicazione DEVE essere in grado di specificare l'indirizzo IP di origine da utilizzare per l'invio di un datagramma UDP, o lasciarlo non specificato (nel qual caso il software di rete sceglierà un indirizzo di origine appropriato). CI DOVREBBE essere un modo per trasmettere l'indirizzo di origine selezionato al livello applicativo (ad esempio, in modo che l'applicazione possa in seguito ricevere solo datagrammi di risposta dall'interfaccia corrispondente).
DISCUSSIONE:
Le applicazioni di richiesta/risposta che utilizzano UDP dovrebbero utilizzare lo stesso indirizzo di origine per la risposta dell'indirizzo di destinazione specifico della richiesta. Vedere la sezione "General Issues" di [INTRO:1].
4.1.3.6 Indirizzi non validi (Invalid Addresses)
I datagrammi UDP ricevuti con un indirizzo IP di origine non valido (ad esempio, un indirizzo broadcast o multicast) DEVONO essere scartati da UDP o dal livello IP (vedere la sezione 3.2.1.3).
Quando un host invia un datagramma UDP, l'indirizzo di origine DEVE essere uno (o più) degli indirizzi IP dell'host.
4.1.4 INTERFACCIA UDP/LIVELLO APPLICATIVO (UDP/APPLICATION LAYER INTERFACE)
L'interfaccia applicativa di UDP DEVE fornire il set completo di servizi dell'interfaccia IP/trasporto descritta nella sezione 3.4 di questo documento. Pertanto, le applicazioni che utilizzano UDP hanno bisogno delle funzioni GET_SRCADDR(), GET_MAXSIZES(), ADVISE_DELIVPROB() e RECV_ICMP() descritte nella sezione 3.4. Ad esempio, GET_MAXSIZES() può essere utilizzato per conoscere la dimensione massima effettiva del datagramma UDP per una particolare tripla {interfaccia, host remoto, TOS}.
I programmi del livello applicativo DEVONO essere in grado di impostare i valori TTL e TOS per l'invio di un datagramma UDP e le opzioni IP, e questi valori devono essere trasmessi trasparentemente al livello IP. UDP PUÒ trasmettere il TOS ricevuto al livello applicativo.
4.1.5 RIEPILOGO DEI REQUISITI UDP (UDP REQUIREMENTS SUMMARY)
| Funzionalità | Sezione | DEVE | DOVREBBE | PUÒ | NON DEVE |
|---|---|---|---|---|---|
| UDP | |||||
| UDP invia Port Unreachable | 4.1.3.1 | x | |||
| Opzioni IP in UDP | |||||
| - Trasmettere opzioni IP ricevute all'applicazione | 4.1.3.2 | x | |||
| - L'applicazione può specificare opzioni IP durante l'invio | 4.1.3.2 | x | |||
| - UDP trasmette opzioni IP al livello IP | 4.1.3.2 | x | |||
| Trasmettere messaggi ICMP all'applicazione | 4.1.3.3 | x | |||
| Checksum UDP: | |||||
| - Capacità di generare/verificare checksum | 4.1.3.4 | x | |||
| - Scartare silenziosamente checksum non valido | 4.1.3.4 | x | |||
| - Opzione di invio senza generare checksum | 4.1.3.4 | x | |||
| - Checksum attivato per impostazione predefinita | 4.1.3.4 | x | |||
| - Opzione di ricezione che richiede checksum | 4.1.3.4 | x | |||
| Multihoming UDP | |||||
| - Trasmettere indirizzo di destinazione specifico all'applicazione | 4.1.3.5 | x | |||
| - L'applicazione può specificare l'indirizzo IP locale | 4.1.3.5 | x | |||
| - L'applicazione può specificare indirizzo IP locale jolly | 4.1.3.5 | x | |||
| - L'applicazione viene informata dell'indirizzo IP locale utilizzato | 4.1.3.5 | x | |||
| Indirizzo IP di origine non valido scartato da UDP/IP | 4.1.3.6 | x | |||
| Inviare solo indirizzo IP di origine valido | 4.1.3.6 | x | |||
| Servizi interfaccia applicativa UDP | |||||
| Fornire interfaccia IP completa da 3.4 all'applicazione | 4.1.4 | x | |||
| - Specificare TTL, TOS, opzioni IP durante l'invio | 4.1.4 | x | |||
| - Trasmettere TOS ricevuto all'applicazione | 4.1.4 | x |
4.2 PROTOCOLLO DI CONTROLLO DELLA TRASMISSIONE -- TCP (TRANSMISSION CONTROL PROTOCOL)
4.2.1 INTRODUZIONE (INTRODUCTION)
Il Protocollo di Controllo della Trasmissione (Transmission Control Protocol, TCP) [TCP:1] è il principale protocollo di trasporto affidabile orientato alla connessione a circuito virtuale della suite Internet. TCP fornisce consegna affidabile e ordinata di un flusso di byte bidirezionale. TCP è utilizzato da applicazioni che richiedono un servizio di trasporto affidabile orientato alla connessione, come posta (SMTP), trasferimento file (FTP) e servizio di terminale virtuale (Telnet); i requisiti di questi protocolli del livello applicativo sono descritti in [INTRO:1].
4.2.2 PERCORSO DEL PROTOCOLLO (PROTOCOL WALK-THROUGH)
4.2.2.1 Porte ben note (Well-Known Ports): RFC-793 Sezione 2.7
DISCUSSIONE:
TCP riserva i numeri di porta nell'intervallo 0-255 per le porte "ben note", per accedere ai servizi standardizzati su Internet. Il resto dello spazio delle porte può essere assegnato liberamente ai processi applicativi. Le definizioni correnti delle porte ben note sono elencate nell'RFC intitolato "Assigned Numbers" [INTRO:6]. Il prerequisito per definire una nuova porta ben nota è un RFC che documenti il servizio proposto con dettagli sufficienti per consentire nuove implementazioni.
Alcuni sistemi estendono questo concetto aggiungendo una terza suddivisione dello spazio delle porte TCP: porte riservate (reserved ports), che sono tipicamente utilizzate per servizi specifici del sistema operativo. Ad esempio, le porte riservate potrebbero trovarsi tra 256 e un limite superiore dipendente dal sistema. Alcuni sistemi scelgono inoltre di proteggere le porte ben note e le porte riservate consentendo solo agli utenti privilegiati di aprire connessioni TCP con questi valori di porta. Questo è perfettamente ragionevole purché l'host non presuma che tutti gli host proteggano le loro porte con numeri bassi in questo modo.
4.2.2.2 Utilizzo di Push: RFC-793 Sezione 2.8
Quando l'applicazione emette una serie di chiamate SEND senza impostare il flag PUSH, TCP PUÒ buffer i dati internamente senza inviarli. Analogamente, alla ricezione di una serie di segmenti senza il bit PSH, TCP PUÒ mettere in coda i dati internamente senza consegnarli all'applicazione ricevente.
Il bit PSH non è un marcatore di record ed è indipendente dai confini del segmento. Il mittente DOVREBBE aggregare i bit PSH consecutivi durante la pacchettizzazione dei dati per inviare il segmento più grande possibile.
TCP PUÒ implementare il flag PUSH sulla chiamata SEND. Se il flag PUSH non è implementato, allora il TCP di invio: (1) non deve bufferizzare i dati indefinitamente, e (2) DEVE impostare il bit PSH nell'ultimo segmento bufferizzato (cioè, quando non ci sono più dati in coda da inviare).
La discussione in RFC-793 alle pagine 48, 50 e 74 suggerisce erroneamente che il flag PSH ricevuto dovrebbe essere passato al livello applicativo. Il passaggio del flag PSH ricevuto al livello applicativo è ora OPZIONALE.
L'applicazione deve logicamente impostare il flag PUSH in una chiamata SEND ogni volta che ha bisogno di forzare la consegna dei dati per evitare un blocco della comunicazione. Tuttavia, TCP DOVREBBE inviare segmenti di dimensione massima quando possibile per migliorare le prestazioni (vedere la sezione 4.2.3.4).
DISCUSSIONE:
Quando il flag PUSH non è implementato sulle chiamate SEND, cioè quando l'interfaccia applicazione/TCP utilizza un modello di flusso puro, la responsabilità di aggregare piccoli frammenti di dati per formare segmenti di dimensioni ragionevoli ricade in parte sul livello applicativo.
Normalmente, i protocolli applicativi interattivi dovrebbero impostare il flag PUSH almeno sull'ultima chiamata SEND di ogni sequenza di comando o risposta. I protocolli di trasferimento dati in blocco come FTP dovrebbero impostare il flag PUSH sull'ultimo segmento di un file o quando necessario per prevenire un blocco del buffer.
Sul lato ricevente, il bit PSH forza la consegna dei dati bufferizzati all'applicazione (anche se è stato ricevuto meno di un buffer completo di dati). Al contrario, l'assenza del bit PSH può essere utilizzata per evitare chiamate di risveglio non necessarie del processo applicativo; questo può essere un'importante ottimizzazione delle prestazioni per grandi host a condivisione di tempo. Il passaggio del bit PSH all'applicazione ricevente consente ottimizzazioni simili all'interno dell'applicazione.
4.2.2.3 Dimensione finestra: RFC-793 Sezione 3.1
La dimensione della finestra DEVE essere trattata come un numero senza segno, altrimenti le grandi dimensioni della finestra appariranno come finestre negative e TCP non funzionerà. È RACCOMANDATO che le implementazioni riservino campi a 32 bit per le dimensioni della finestra di invio e ricezione nel record di connessione e utilizzino 32 bit per tutti i calcoli della finestra.
DISCUSSIONE:
Il campo finestra nell'intestazione TCP è notoriamente troppo piccolo per percorsi ad alta velocità e lunga distanza. Sono state definite opzioni TCP sperimentali per estendere la dimensione della finestra; vedere ad esempio [TCP:11]. Per anticipare l'adozione di tali estensioni, gli implementatori TCP dovrebbero trattare la finestra come a 32 bit.
4.2.2.4 Puntatore urgente: RFC-793 Sezione 3.1
C'è un errore nella seconda frase: il puntatore urgente punta al numero di sequenza dell'ultimo byte (non LAST+1) della sequenza di dati urgenti. La descrizione a pagina 56 (ultima frase) è corretta.
TCP DEVE supportare sequenze di dati urgenti di lunghezza arbitraria.
TCP DEVE notificare in modo asincrono il livello applicativo quando viene ricevuto un puntatore urgente e non ci sono dati urgenti in sospeso precedenti, o ogni volta che il puntatore urgente avanza nel flusso di dati. CI DEVE essere un modo per l'applicazione di sapere quanti dati urgenti rimangono da leggere dalla connessione, o almeno di determinare se ci sono ancora più dati urgenti da leggere.
DISCUSSIONE:
Sebbene il meccanismo urgente possa essere utilizzato da qualsiasi applicazione, è normalmente utilizzato per inviare comandi di tipo "interrupt" ai programmi Telnet (vedere la sezione "Use of Telnet Synch Sequence" in [INTRO:1]).
La notifica asincrona o "fuori banda" consentirà all'applicazione di entrare in "modalità urgente", leggendo i dati dalla connessione TCP. Ciò consente di inviare comandi di controllo a un'applicazione il cui buffer di input normale è pieno di dati non elaborati.
IMPLEMENTAZIONE:
La chiamata verso l'alto generica ERROR-REPORT() descritta nella sezione 4.2.4.1 è un possibile meccanismo per notificare all'applicazione l'arrivo di dati urgenti.
4.2.2.5 Opzioni TCP: RFC-793 Sezione 3.1
TCP DEVE essere in grado di ricevere opzioni TCP in qualsiasi segmento. TCP DEVE ignorare qualsiasi opzione TCP che non implementa senza errore, assumendo che l'opzione abbia un campo di lunghezza (tutte le opzioni TCP definite in futuro avranno un campo di lunghezza). TCP DEVE essere pronto a gestire una lunghezza di opzione illegale (ad esempio, zero) senza crash; la procedura suggerita è di resettare la connessione e registrare il motivo.
4.2.2.6 Opzione dimensione massima del segmento: RFC-793 Sezione 3.1
TCP DEVE implementare l'invio e la ricezione dell'opzione Maximum Segment Size (MSS) [TCP:4].
TCP DOVREBBE inviare un'opzione MSS in ogni segmento SYN quando il suo MSS di ricezione differisce dal valore predefinito 536, e PUÒ sempre inviarla.
Se non viene ricevuta alcuna opzione MSS durante l'instaurazione della connessione, TCP DEVE assumere un MSS di invio predefinito di 536 (576-40) [TCP:4].
La dimensione massima dei segmenti che TCP effettivamente invia, l'"MSS di invio effettivo", DEVE essere il minimo tra l'MSS di invio (che riflette la dimensione del buffer di riassemblaggio disponibile dell'host remoto) e la dimensione massima consentita dal livello IP:
Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize
dove:
- SendMSS è il valore MSS ricevuto dall'host remoto, o il valore predefinito 536 se non è stata ricevuta alcuna opzione MSS.
- MMS_S è la dimensione massima di un messaggio del livello di trasporto che TCP può inviare.
- TCPhdrsize è la dimensione dell'intestazione TCP; questo è normalmente 20, ma può essere più grande se devono essere inviate opzioni TCP.
- IPoptionsize è la dimensione di tutte le opzioni IP che TCP passerà al livello IP con il messaggio corrente.
Il valore MSS da inviare in un'opzione MSS deve essere minore o uguale a:
MMS_R - 20
dove MMS_R è la dimensione massima di un messaggio del livello di trasporto che può essere ricevuto (e riassemblato). TCP ottiene MMS_R e MMS_S dal livello IP; vedere la chiamata generica GET_MAXSIZES nella sezione 3.4.
DISCUSSIONE:
La scelta della dimensione del segmento TCP ha un forte effetto sulle prestazioni. I segmenti più grandi migliorano il throughput ammortizzando la dimensione dell'intestazione e le spese generali di elaborazione per datagramma su più byte di dati; tuttavia, se il pacchetto è così grande da causare frammentazione IP, l'efficienza diminuisce drasticamente se un frammento viene perso [IP:9].
Alcune implementazioni TCP inviano l'opzione MSS solo se l'host di destinazione si trova su una rete non connessa. Tuttavia, in generale, il livello TCP potrebbe non avere le informazioni appropriate per prendere questa decisione, quindi è meglio lasciare al livello IP il compito di determinare l'MTU appropriato per il percorso Internet. Pertanto, raccomandiamo che TCP invii sempre l'opzione (se non è 536) e che il livello IP determini MMS_R come specificato nelle sezioni 3.3.3 e 3.4. Il meccanismo del livello IP proposto per misurare l'MTU cambierebbe quindi il livello IP senza cambiare TCP.
4.2.2.7 Checksum TCP: RFC-793 Sezione 3.1
A differenza del checksum UDP (vedere la sezione 4.1.3.4), il checksum TCP non è mai opzionale. Il mittente DEVE generarlo e il ricevitore DEVE verificarlo.
4.2.2.8 Diagramma di stato della connessione TCP: RFC-793 Sezione 3.2, pagina 23
Ci sono diversi problemi con questo diagramma:
(a) La freccia da SYN-SENT a SYN-RCVD dovrebbe essere etichettata "snd SYN,ACK", per essere coerente con il testo a pagina 68 e la figura 8.
(b) Potrebbe esserci una freccia dallo stato SYN-RCVD allo stato LISTEN, condizionata dalla ricezione di un RST dopo un'apertura passiva (vedere il testo a pagina 70).
(c) È possibile andare direttamente dallo stato FIN-WAIT-1 allo stato TIME-WAIT (vedere pagina 75 della specifica).
4.2.2.9 Selezione del numero di sequenza iniziale: RFC-793 Sezione 3.3, pagina 27
TCP DEVE utilizzare la selezione del numero di sequenza iniziale guidata dall'orologio specificata.
4.2.2.10 Tentativi di apertura simultanea: RFC-793 Sezione 3.4
C'è un errore nella figura 8: il pacchetto alla riga 7 dovrebbe essere identico al pacchetto alla riga 5.
TCP DEVE supportare tentativi di apertura simultanea.
DISCUSSIONE:
A volte sorprende gli implementatori che se due applicazioni tentano di connettersi simultaneamente l'una all'altra, viene generata solo una connessione invece di due. Questa è stata una decisione di progettazione intenzionale; non cercare di "correggerla".
4.2.2.11 Recupero da vecchio SYN duplicato: RFC-793 Sezione 3.4, pagina 33
Si noti che un'implementazione TCP DEVE tenere traccia se la connessione ha raggiunto lo stato SYN_RCVD come risultato di un OPEN passivo o di un OPEN attivo.
4.2.2.12 Segmento RST: RFC-793 Sezione 3.4
TCP DOVREBBE consentire a un segmento RST ricevuto di contenere dati.
DISCUSSIONE:
È stato suggerito che un segmento RST potrebbe contenere testo ASCII che codifica e spiega la causa del RST. Non è ancora stato stabilito alcuno standard per tali dati.
4.2.2.13 Chiusura di una connessione: RFC-793 Sezione 3.5
Una connessione TCP può terminare in due modi: (1) la normale sequenza di chiusura TCP utilizzando un handshake FIN, e (2) un "abort" in cui vengono inviati uno o più segmenti RST e lo stato di connessione viene immediatamente cancellato. Se una connessione TCP è chiusa dal sito remoto, l'applicazione locale DEVE essere informata se è stata chiusa normalmente o è stata abortita.
La normale sequenza di chiusura TCP consegna in modo affidabile i dati bufferizzati in entrambe le direzioni. Poiché le due direzioni di una connessione TCP sono chiuse indipendentemente, è possibile che una connessione sia "semi-chiusa", cioè chiusa in una sola direzione, e un host è autorizzato a continuare a inviare dati nella direzione aperta su una connessione semi-chiusa.
Un host PUÒ implementare una sequenza di chiusura TCP "half-duplex", in modo che un'applicazione che ha chiamato CLOSE non possa continuare a leggere dati dalla connessione. Se tale host emette una chiamata CLOSE mentre i dati ricevuti sono ancora in sospeso in TCP, o se vengono ricevuti nuovi dati dopo la chiamata CLOSE, il suo TCP DOVREBBE inviare un RST per mostrare che i dati sono stati persi.
Quando una connessione viene chiusa attivamente, DEVE rimanere nello stato TIME-WAIT per un tempo di 2×MSL (Maximum Segment Lifetime). Tuttavia, PUÒ accettare un nuovo SYN dal TCP remoto per riaprire la connessione direttamente dallo stato TIME-WAIT, se:
(1) assegna il suo numero di sequenza iniziale per la nuova connessione in modo che sia maggiore del numero di sequenza più grande che ha utilizzato sull'incarnazione di connessione precedente, e
(2) ritorna allo stato TIME-WAIT se il SYN si rivela essere un vecchio duplicato.
DISCUSSIONE:
La chiusura completa full-duplex con conservazione dei dati di TCP è una caratteristica che non è inclusa nel protocollo di trasporto ISO analogo TP4.
Alcuni sistemi non hanno implementato connessioni semi-chiuse, probabilmente perché non si adattano al modello I/O del loro particolare sistema operativo. Su questi sistemi, una volta che un'applicazione ha chiamato CLOSE, non può più leggere dati di input dalla connessione; questo è chiamato una sequenza di chiusura TCP "half-duplex".
L'algoritmo di chiusura graduale TCP richiede che lo stato di connessione rimanga definito su (almeno) un'estremità della connessione per un periodo di timeout di 2×MSL, cioè 4 minuti. Durante questo periodo, la coppia (socket remoto, socket locale) che definisce la connessione è occupata e non può essere riutilizzata. Per abbreviare il tempo durante il quale una data coppia di socket è occupata, alcuni TCP consentono che un nuovo SYN venga accettato nello stato TIME-WAIT.
4.2.2.14 Comunicazione dati: RFC-793 Sezione 3.7, pagina 40
Dal momento in cui è stato scritto RFC-793, c'è stato un lavoro estensivo sugli algoritmi TCP per ottenere una comunicazione dati efficiente. Le sezioni successive di questo documento descrivono gli algoritmi TCP richiesti e raccomandati per determinare quando inviare dati (sezione 4.2.3.4), quando inviare un riconoscimento (sezione 4.2.3.2) e quando aggiornare la finestra (sezione 4.2.3.3).
DISCUSSIONE:
Un importante problema di prestazioni è la "sindrome della finestra sciocca" o "SWS" [TCP:5], un modello stabile di piccoli movimenti incrementali della finestra che risultano in prestazioni TCP estremamente scadenti. Gli algoritmi per evitare SWS sono descritti di seguito per il lato di invio (sezione 4.2.3.4) e il lato di ricezione (sezione 4.2.3.3).
In breve, SWS è causato dal ricevitore che avanza il bordo destro della finestra ogni volta che ha nuovo spazio buffer disponibile per ricevere dati e dal mittente che utilizza qualsiasi finestra incrementale, per quanto piccola, per inviare più dati [TCP:5]. Il risultato può essere un modello stabile di invio di segmenti di dati minuscoli, anche se sia il mittente che il ricevitore hanno entrambi un grande spazio buffer totale per la connessione. SWS può verificarsi solo durante la trasmissione di una grande quantità di dati; se la connessione diventa inattiva, il problema scompare. È causato da un'implementazione tipica semplice della gestione della finestra, ma gli algoritmi del mittente e del ricevitore forniti di seguito lo eviteranno.
Un altro importante problema di prestazioni TCP è che alcune applicazioni, in particolare il login remoto carattere per carattere agli host, tendono a inviare flussi di segmenti di dati a un byte. Per evitare deadlock, ogni chiamata TCP SEND di tali applicazioni deve essere "pushed", esplicitamente dall'applicazione o implicitamente da TCP. Il risultato può essere un flusso di segmenti TCP contenenti ciascuno un byte di dati, il che rende l'uso di Internet molto inefficiente e contribuisce alla congestione di Internet. L'algoritmo di Nagle descritto nella sezione 4.2.3.4 fornisce una soluzione semplice ed efficace a questo problema. Ha l'effetto di raggruppare i caratteri sulle connessioni Telnet; questo può inizialmente sorprendere gli utenti abituati all'eco di un singolo carattere, ma questo raggruppamento è vantaggioso sia per la rete che per il tempo di risposta dell'utente.
L'accettazione da parte degli utenti non è stata un problema.
Si noti che l'algoritmo di Nagle e l'algoritmo di prevenzione SWS di invio svolgono ruoli complementari nel migliorare le prestazioni. L'algoritmo di Nagle scoraggia l'invio di segmenti minuscoli quando i dati da inviare aumentano in piccoli incrementi, mentre l'algoritmo di prevenzione SWS scoraggia i piccoli segmenti risultanti dall'avanzamento del bordo destro della finestra in piccoli incrementi.
Un'implementazione negligente può inviare due o più segmenti di riconoscimento per segmento di dati ricevuto. Ad esempio, supponiamo che il ricevitore riconosca ogni segmento di dati immediatamente. Quando il programma applicativo consuma quindi i dati e aumenta nuovamente lo spazio buffer di ricezione disponibile, il ricevitore può inviare un secondo segmento di riconoscimento per aggiornare la finestra del mittente. Il caso estremo si verifica con segmenti a singolo carattere su connessioni TCP utilizzando il protocollo Telnet per il servizio di login remoto. Alcune implementazioni sono state osservate in cui ogni segmento in ingresso di un carattere genera tre segmenti di ritorno: (1) il riconoscimento, (2) un aumento di un byte della finestra e (3) il carattere di eco, rispettivamente.
4.2.2.15 Timeout di ritrasmissione: RFC-793 Sezione 3.7, pagina 41
L'algoritmo suggerito in RFC-793 per calcolare il timeout di ritrasmissione è ora noto per essere inadeguato; vedere la sezione 4.2.3.1 sotto.
Il lavoro recente di Jacobson [TCP:7] sulla congestione di Internet e la stabilità di ritrasmissione TCP ha prodotto un algoritmo di trasmissione combinato che unisce "slow start" con "congestion avoidance". Un TCP DEVE implementare questo algoritmo.
Se un pacchetto ritrasmesso è identico al pacchetto originale (il che implica non solo che i confini dei dati non sono cambiati, ma anche che i campi finestra e riconoscimento dell'intestazione non sono cambiati), allora lo stesso campo Identificazione IP PUÒ essere utilizzato (vedere la sezione 3.2.1.5).
IMPLEMENTAZIONE:
Alcuni implementatori TCP hanno scelto di "pacchettizzare" il flusso di dati, cioè scegliere i confini dei segmenti quando i segmenti vengono inizialmente inviati e mettere in coda questi segmenti in una "coda di ritrasmissione" fino a quando non vengono riconosciuti. Un altro design (che potrebbe essere più semplice) è di differire la pacchettizzazione fino a ogni volta che i dati vengono trasmessi o ritrasmessi, in modo che non ci sarà alcuna coda di ritrasmissione dei segmenti.
In un'implementazione con una coda di ritrasmissione dei segmenti, le prestazioni TCP possono essere migliorate ripacketizzando i segmenti in attesa di riconoscimento quando si verifica il primo timeout di ritrasmissione. Cioè, i segmenti in sospeso che si adatterebbero sarebbero combinati in un segmento di dimensione massima, con un nuovo valore di Identificazione. Il TCP manterrebbe quindi questo segmento combinato nella coda di ritrasmissione fino a quando non viene riconosciuto. Tuttavia, se i primi due segmenti nella coda di ritrasmissione totalizzassero più di un segmento di dimensione massima, il TCP ritrasmetterebbe solo il primo segmento utilizzando il campo Identificazione originale.
4.2.2.16 Gestione della finestra: RFC-793 Sezione 3.7, pagina 41
Un TCP ricevente NON DOVREBBE ridurre la finestra, cioè spostare il bordo destro della finestra a sinistra. Tuttavia, un TCP di invio DEVE essere robusto contro la riduzione della finestra, che può far diventare negativa la "finestra utilizzabile" (vedere la sezione 4.2.3.4).
Se ciò accade, il mittente NON DOVREBBE inviare nuovi dati, ma DOVREBBE ritrasmettere normalmente i vecchi dati non riconosciuti tra SND.UNA e SND.UNA+SND.WND. Il mittente PUÒ anche ritrasmettere vecchi dati oltre SND.UNA+SND.WND, ma NON DOVREBBE terminare la connessione per timeout se i dati oltre il bordo destro della finestra non vengono riconosciuti. Se la finestra si riduce a zero, il TCP DEVE sondarla nel modo standard (vedere la sezione successiva).
DISCUSSIONE:
Molte implementazioni TCP diventano confuse se la finestra si riduce da destra dopo che i dati sono stati inviati in una finestra più grande. Si noti che TCP ha un'euristica per selezionare l'ultimo aggiornamento della finestra nonostante il possibile riordino dei datagrammi; di conseguenza, può ignorare un aggiornamento della finestra con una finestra più piccola di quella offerta in precedenza se né il numero di sequenza né il numero di riconoscimento vengono aumentati.
4.2.2.17 Sondaggio delle finestre zero: RFC-793 Sezione 3.7, pagina 42
Il sondaggio delle finestre zero (offerte) DEVE essere supportato.
Un TCP PUÒ mantenere la sua finestra di ricezione offerta chiusa indefinitamente. Finché il TCP ricevente continua a inviare riconoscimenti in risposta ai segmenti di sondaggio, il TCP di invio DEVE consentire alla connessione di rimanere aperta.
DISCUSSIONE:
È estremamente importante ricordare che i segmenti ACK (riconoscimento) che non contengono dati non sono trasmessi in modo affidabile da TCP. Se il sondaggio delle finestre zero non è supportato, una connessione può bloccarsi indefinitamente quando un segmento ACK che riapre la finestra viene perso.
Il ritardo nell'apertura di una finestra zero si verifica normalmente quando l'applicazione ricevente smette di prendere dati dal suo TCP. Ad esempio, considera un'applicazione daemon stampante, arrestata perché la stampante ha esaurito la carta.
L'host trasmittente DOVREBBE inviare il primo sondaggio di finestra zero quando una finestra zero è esistita per il periodo di timeout di ritrasmissione (vedere la sezione 4.2.2.15), e DOVREBBE aumentare esponenzialmente l'intervallo tra sondaggi successivi.
DISCUSSIONE:
Questa procedura minimizza il ritardo se la condizione di finestra zero è dovuta a un segmento ACK perso contenente un aggiornamento di apertura della finestra. Il backoff esponenziale è raccomandato, possibilmente con un intervallo massimo non specificato qui. Questa procedura è simile a quella dell'algoritmo di ritrasmissione, e potrebbe essere possibile combinare le due procedure nell'implementazione.
4.2.2.18 Chiamate OPEN passive: RFC-793 Sezione 3.8
Ogni chiamata OPEN passiva crea un nuovo record di connessione nello stato LISTEN o restituisce un errore; NON DEVE influenzare un record di connessione precedentemente creato.
Un TCP che supporta più utenti simultanei DEVE fornire una chiamata OPEN che consentirà funzionalmente a un'applicazione di LISTEN su una porta mentre un blocco di connessione con la stessa porta locale è nello stato SYN-SENT o SYN-RECEIVED.
DISCUSSIONE:
Alcune applicazioni (ad esempio, server SMTP) potrebbero dover gestire più tentativi di connessione approssimativamente nello stesso momento. La probabilità che un tentativo di connessione fallisca viene ridotta dando all'applicazione un modo per ascoltare una nuova connessione mentre un tentativo di connessione precedente passa attraverso l'handshake a tre vie.
IMPLEMENTAZIONE:
Implementazioni accettabili di aperture simultanee possono consentire più chiamate OPEN passive, oppure possono consentire la "clonazione" di connessioni in stato LISTEN da una singola chiamata OPEN passiva.
4.2.2.19 Time to Live: RFC-793 Sezione 3.9, pagina 52
RFC-793 specificava che TCP dovrebbe richiedere al livello IP di inviare segmenti TCP con TTL = 60. Questo è obsoleto; il valore TTL utilizzato per inviare segmenti TCP DEVE essere configurabile. Vedere la sezione 3.2.1.7 per la discussione.
4.2.2.20 Elaborazione degli eventi: RFC-793 Sezione 3.9
Sebbene non sia strettamente richiesto, un TCP DOVREBBE essere in grado di mettere in coda segmenti fuori sequenza. Cambiare il "may" nell'ultima frase del primo paragrafo a pagina 70 in "should".
DISCUSSIONE:
Alcune implementazioni di host piccoli hanno omesso la coda dei segmenti a causa dello spazio buffer limitato. Si prevede che questa omissione influenzi negativamente il throughput TCP, poiché la perdita di un singolo segmento fa apparire tutti i segmenti successivi come "fuori sequenza".
In generale, l'elaborazione dei segmenti ricevuti DEVE essere implementata per aggregare i segmenti ACK quando possibile. Ad esempio, se il TCP elabora una serie di segmenti in coda, DEVE elaborarli tutti prima di inviare segmenti ACK.
Ecco alcune correzioni di errori dettagliate e note sulla sezione Event Processing di RFC-793.
(a) Chiamata CLOSE, stato CLOSE-WAIT, p. 61: entrare nello stato LAST-ACK, non CLOSING.
(b) Stato LISTEN, controllare SYN (pp. 65, 66): Con un bit SYN, se la sicurezza/compartment o la precedenza è errata per il segmento, viene inviato un reset. La forma errata del reset è mostrata nel testo; dovrebbe essere:
<SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>
(c) Stato SYN-SENT, Controllare SYN, p. 68: Quando la connessione entra nello stato ESTABLISHED, le seguenti variabili dovrebbero essere impostate:
SND.WND <- SEG.WND
SND.WL1 <- SEG.SEQ
SND.WL2 <- SEG.ACK
(d) Controllare sicurezza e precedenza, p. 71: Il primo header "ESTABLISHED STATE" dovrebbe davvero essere un elenco di tutti gli stati diversi da SYN-RECEIVED: ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK e TIME-WAIT.
(e) Controllare bit SYN, p. 71: "Nello stato SYN-RECEIVED e se la connessione è stata avviata con un OPEN passivo, quindi riportare questa connessione allo stato LISTEN e tornare. Altrimenti...".
(f) Controllare campo ACK, stato SYN-RECEIVED, p. 72: Quando la connessione entra nello stato ESTABLISHED, le variabili elencate in (c) dovrebbero essere impostate.
(g) Controllare campo ACK, stato ESTABLISHED, p. 72: L'ACK è un duplicato se SEG.ACK =< SND.UNA (il = è stato omesso). Allo stesso modo, la finestra dovrebbe essere aggiornata se: SND.UNA =< SEG.ACK =< SND.NXT.
(h) USER TIMEOUT, p. 77:
Sarebbe meglio notificare all'applicazione il timeout piuttosto che lasciare che TCP forzi la chiusura della connessione. Tuttavia, vedere anche la sezione 4.2.3.5.
4.2.2.21 Riconoscimento di segmenti in coda: RFC-793 Sezione 3.9
Un TCP PUÒ inviare un segmento ACK che riconosce RCV.NXT quando arriva un segmento valido che è nella finestra ma non al bordo sinistro della finestra.
DISCUSSIONE:
RFC-793 (vedere pagina 74) era ambiguo sul fatto che un segmento ACK dovesse essere inviato o meno quando veniva ricevuto un segmento fuori sequenza, cioè quando SEG.SEQ non era uguale a RCV.NXT.
Un motivo per riconoscere i segmenti fuori sequenza potrebbe essere supportare un algoritmo sperimentale noto come "fast retransmit". Con questo algoritmo, il mittente utilizza ACK "ridondanti" per dedurre che un segmento è stato perso prima che scada il timer di ritrasmissione. Conta il numero di volte in cui è stato ricevuto un ACK con lo stesso valore SEG.ACK e lo stesso bordo destro della finestra. Se viene ricevuto più di un numero soglia di tali ACK, allora si presume che il segmento contenente i byte che iniziano con SEG.ACK sia stato perso e viene ritrasmesso, senza attendere un timeout. La soglia è scelta per compensare il massimo riordino probabile di segmenti in Internet. Non c'è ancora abbastanza esperienza con l'algoritmo fast retransmit per determinarne l'utilità.
4.2.3 PROBLEMI SPECIFICI (SPECIFIC ISSUES)
4.2.3.1 Calcolo del timeout di ritrasmissione (Retransmission Timeout Calculation)
Un TCP host DEVE implementare l'algoritmo di Karn e l'algoritmo di Jacobson per calcolare il timeout di ritrasmissione ("RTO").
-
L'algoritmo di Jacobson per calcolare il tempo di andata e ritorno ("RTT") levigato incorpora una semplice misura della varianza [TCP:7].
-
L'algoritmo di Karn per selezionare le misure RTT garantisce che i tempi di andata e ritorno ambigui non corrompano il calcolo del tempo di andata e ritorno levigato [TCP:6].
Questa implementazione DEVE anche includere un "backoff esponenziale" per i valori RTO successivi per lo stesso segmento. La ritrasmissione dei segmenti SYN DOVREBBE utilizzare lo stesso algoritmo dei segmenti di dati.
DISCUSSIONE:
Ci sono stati due problemi noti con i calcoli RTO specificati in RFC-793. Primo, la misurazione accurata degli RTT è difficile quando ci sono ritrasmissioni. Secondo, l'algoritmo per calcolare il tempo di andata e ritorno levigato è inadeguato [TCP:7], poiché presupponeva erroneamente che la varianza nei valori RTT sarebbe piccola e costante. Questi problemi sono stati risolti dagli algoritmi di Karn e Jacobson, rispettivamente.
Il miglioramento delle prestazioni risultante dall'uso di questi miglioramenti varia da notevole a drammatico. L'algoritmo di Jacobson per incorporare la varianza RTT misurata è particolarmente importante su un collegamento a bassa velocità, dove la variazione naturale delle dimensioni dei pacchetti causa una grande variazione di RTT. Un fornitore ha scoperto che l'utilizzo del collegamento su una linea 9,6kb è aumentato dal 10% al 90% dopo l'implementazione dell'algoritmo della varianza di Jacobson in TCP.
I seguenti valori DOVREBBERO essere utilizzati per inizializzare i parametri di stima per una nuova connessione:
(a) RTT = 0 secondi.
(b) RTO = 3 secondi. (La varianza levigata dovrebbe essere inizializzata al valore che porterà a questo RTO).
I limiti superiore e inferiore raccomandati sull'RTO sono noti per essere inadeguati per grandi internet. Il limite inferiore DOVREBBE essere misurato in frazioni di secondo (per ospitare LAN ad alta velocità) e il limite superiore dovrebbe essere 2×MSL, cioè 240 secondi.
DISCUSSIONE:
L'esperienza ha dimostrato che questi valori di inizializzazione sono ragionevoli e che in ogni caso gli algoritmi di Karn e Jacobson rendono il comportamento TCP ragionevolmente insensibile alle scelte iniziali dei parametri.
4.2.3.2 Quando inviare un segmento ACK (When to Send an ACK Segment)
Un host che riceve un flusso di segmenti di dati TCP può aumentare l'efficienza sia in Internet che negli host inviando meno di un segmento ACK (riconoscimento) per segmento di dati ricevuto; questo è noto come "ACK ritardato" [TCP:5].
Un TCP DOVREBBE implementare un ACK ritardato, ma un ACK non dovrebbe essere eccessivamente ritardato; in particolare, il ritardo DEVE essere inferiore a 0,5 secondi e in un flusso di segmenti di dimensione completa, CI DOVREBBE essere un ACK per almeno ogni secondo segmento.
DISCUSSIONE:
Un ACK ritardato dà all'applicazione l'opportunità di aggiornare la finestra e forse di inviare una risposta immediata. In particolare, nel caso del login remoto in modalità carattere, un ACK ritardato può ridurre il numero di segmenti inviati dal server di un fattore 3 (ACK, aggiornamento finestra e carattere eco tutti combinati in un segmento).
Inoltre, su alcuni grandi host multi-utente, un ACK ritardato può ridurre significativamente le spese generali di elaborazione del protocollo riducendo il numero totale di pacchetti da elaborare [TCP:5]. Tuttavia, ritardi eccessivi sugli ACK possono disturbare il cronometraggio di andata e ritorno e gli algoritmi di "clocking" dei pacchetti [TCP:7].
4.2.3.3 Quando inviare un aggiornamento della finestra (When to Send a Window Update)
Un TCP DEVE includere un algoritmo di prevenzione SWS nel ricevitore [TCP:5].
IMPLEMENTAZIONE:
L'algoritmo di prevenzione SWS del ricevitore determina quando il bordo destro della finestra può essere avanzato; questo è di solito noto come "aggiornamento della finestra". Questo algoritmo si combina con l'algoritmo ACK ritardato (vedere la sezione 4.2.3.2) per determinare quando un segmento ACK contenente la finestra corrente verrà effettivamente inviato al ricevitore. Usiamo la notazione di RFC-793; vedere le figure 4 e 5 in quel documento.
La soluzione per lo SWS del ricevitore è evitare di avanzare il bordo destro della finestra RCV.NXT+RCV.WND in piccoli incrementi, anche se i dati vengono ricevuti dalla rete in piccoli segmenti.
Supponiamo che lo spazio buffer di ricezione totale sia RCV.BUFF. In un dato momento, RCV.USER byte di questo totale possono essere legati a dati che sono stati ricevuti e riconosciuti ma non ancora consumati dal processo utente. Quando la connessione è inattiva, RCV.WND = RCV.BUFF e RCV.USER = 0.
Mantenere fisso il bordo destro della finestra mentre i dati arrivano e vengono riconosciuti richiede che il ricevitore offra meno del suo spazio buffer completo, cioè il ricevitore deve specificare un RCV.WND che mantiene RCV.NXT+RCV.WND costante mentre RCV.NXT aumenta. Così, lo spazio buffer totale RCV.BUFF è generalmente diviso in tre parti:
|<------- RCV.BUFF ---------------->|
1 2 3
----|---------|------------------|------|----
RCV.NXT ^
(Fixed)
1 - RCV.USER = dati ricevuti ma non ancora consumati;
2 - RCV.WND = spazio annunciato al mittente;
3 - Reduction = spazio disponibile ma non ancora annunciato.
L'algoritmo di prevenzione SWS suggerito per il ricevitore è mantenere RCV.NXT+RCV.WND fisso fino a quando la riduzione soddisfa:
RCV.BUFF - RCV.USER - RCV.WND >= min(Fr * RCV.BUFF, Eff.snd.MSS)
dove Fr è una frazione il cui valore raccomandato è 1/2, ed Eff.snd.MSS è l'MSS di invio effettivo per la connessione (vedere la sezione 4.2.2.6). Quando la disuguaglianza è soddisfatta, RCV.WND è impostato su RCV.BUFF-RCV.USER.
Si noti che l'effetto complessivo di questo algoritmo è far avanzare RCV.WND in incrementi di Eff.snd.MSS (per buffer di ricezione realistici: Eff.snd.MSS < RCV.BUFF/2). Si noti anche che il ricevitore deve utilizzare il proprio Eff.snd.MSS, presumendo che sia lo stesso del mittente.
4.2.3.4 Quando inviare dati (When to Send Data)
Un TCP DEVE includere un algoritmo di prevenzione SWS nel mittente.
Un TCP DOVREBBE implementare l'algoritmo di Nagle [TCP:9] per raggruppare segmenti corti. Tuttavia, CI DEVE essere un modo per un'applicazione di disabilitare l'algoritmo di Nagle su una singola connessione. In ogni caso, l'invio di dati è anche soggetto alla limitazione imposta dall'algoritmo di slow start (sezione 4.2.2.15).
DISCUSSIONE:
L'algoritmo di Nagle è generalmente il seguente:
Se ci sono dati non riconosciuti (cioè, SND.NXT > SND.UNA), allora il TCP di invio bufferizza tutti i dati utente (indipendentemente dal bit PSH), fino a quando i dati in sospeso sono stati riconosciuti o fino a quando il TCP può inviare un segmento di dimensione completa (Eff.snd.MSS byte; vedere la sezione 4.2.2.6).
Alcune applicazioni (ad esempio, aggiornamenti di finestre di visualizzazione in tempo reale) richiedono che l'algoritmo di Nagle sia disabilitato, in modo che piccoli segmenti di dati possano essere trasmessi alla velocità massima.
IMPLEMENTAZIONE:
L'algoritmo di prevenzione SWS del mittente è più difficile di quello del ricevitore, perché il mittente non conosce (direttamente) lo spazio buffer totale del ricevitore RCV.BUFF. Un approccio che ha funzionato bene è che il mittente calcoli Max(SND.WND), la finestra di invio massima che ha visto finora sulla connessione, e utilizzi questo valore come stima per RCV.BUFF. Sfortunatamente, questa può essere solo una stima; il ricevitore può ridurre la dimensione di RCV.BUFF in qualsiasi momento. Per evitare un deadlock risultante, è necessario avere un timeout per forzare la trasmissione dei dati, annullando l'algoritmo di prevenzione SWS. In pratica, questo timeout dovrebbe verificarsi raramente.
La "finestra utilizzabile" [TCP:5] è:
U = SND.UNA + SND.WND - SND.NXT
cioè, la finestra offerta meno la quantità di dati inviati ma non riconosciuti. Se D è la quantità di dati in coda nel TCP di invio ma non ancora inviati, allora si raccomanda il seguente insieme di regole.
Inviare dati:
(1) se un segmento di dimensione massima può essere inviato, cioè se:
min(D,U) >= Eff.snd.MSS;
(2) o se i dati sono pushed e tutti i dati in coda possono essere inviati ora, cioè se:
[SND.NXT = SND.UNA and] PUSHED and D <= U
(la condizione tra parentesi è imposta dall'algoritmo di Nagle);
(3) o se almeno una frazione Fs della finestra massima può essere inviata, cioè se:
[SND.NXT = SND.UNA and]
min(D,U) >= Fs * Max(SND.WND);
(4) o se i dati sono PUSHed e si verifica il timeout di override.
Qui Fs è una frazione il cui valore raccomandato è 1/2. Il timeout di override dovrebbe essere nell'intervallo 0,1 - 1,0 secondi. Potrebbe essere conveniente combinare questo timer con il timer utilizzato per sondare le finestre zero (sezione 4.2.2.17).
Infine, si noti che l'algoritmo di prevenzione SWS appena specificato dovrebbe essere utilizzato al posto dell'algoritmo lato mittente contenuto in [TCP:5].
4.2.3.5 Fallimenti di connessione TCP (TCP Connection Failures)
La ritrasmissione eccessiva dello stesso segmento da parte di TCP indica un fallimento dell'host remoto o del percorso Internet. Questo fallimento può essere di breve o lunga durata. La seguente procedura DEVE essere utilizzata per gestire ritrasmissioni eccessive di segmenti di dati [IP:11]:
(a) Ci sono due soglie R1 e R2 che misurano la quantità di ritrasmissione che si è verificata per lo stesso segmento. R1 e R2 possono essere misurate in unità di tempo o come conteggio di ritrasmissioni.
(b) Quando il numero di trasmissioni dello stesso segmento raggiunge o supera la soglia R1, trasmettere un avviso negativo (vedere la sezione 3.3.1.4) al livello IP, per attivare la diagnosi di gateway morto.
(c) Quando il numero di trasmissioni dello stesso segmento raggiunge una soglia R2 maggiore di R1, chiudere la connessione.
(d) Un'applicazione DEVE essere in grado di impostare il valore di R2 per una connessione particolare. Ad esempio, un'applicazione interattiva potrebbe impostare R2 su "infinito", dando all'utente il controllo su quando disconnettersi.
(e) TCP DOVREBBE informare l'applicazione del problema di consegna (a meno che tali informazioni non siano state disabilitate dall'applicazione; vedere la sezione 4.2.4.1), quando R1 viene raggiunto e prima che R2 venga raggiunto. Ciò consentirà a un'applicazione di login remoto (User Telnet) di informare l'utente, ad esempio.
Il valore di R1 DOVREBBE corrispondere almeno a 3 ritrasmissioni, all'RTO corrente. Il valore di R2 DOVREBBE corrispondere almeno a 100 secondi.
Un tentativo di apertura di una connessione TCP potrebbe fallire con ritrasmissioni eccessive del segmento SYN o con la ricezione di un segmento RST o di un Port Unreachable ICMP. Le ritrasmissioni SYN DEVONO essere gestite nel modo generale appena descritto per le ritrasmissioni di dati, inclusa la notifica al livello applicativo.
Tuttavia, i valori di R1 e R2 possono essere diversi per i segmenti SYN e di dati. In particolare, R2 per un segmento SYN DEVE essere impostato abbastanza grande da fornire la ritrasmissione del segmento per almeno 3 minuti. L'applicazione può chiudere la connessione (cioè, abbandonare il tentativo di apertura) prima, naturalmente.
DISCUSSIONE:
Alcuni percorsi Internet hanno tempi di configurazione significativi, e il numero di tali percorsi è probabile che aumenti in futuro.
4.2.3.6 Keep-Alive TCP
Gli implementatori POSSONO includere "keep-alives" nelle loro implementazioni TCP, anche se questa pratica non è universalmente accettata. Se i keep-alives sono inclusi, l'applicazione DEVE essere in grado di attivarli o disattivarli per ogni connessione TCP, e DEVONO essere disattivati per impostazione predefinita.
I pacchetti keep-alive DEVONO essere inviati SOLO quando nessun pacchetto di dati o riconoscimento è stato ricevuto per la connessione in un intervallo. Questo intervallo DEVE essere configurabile e DEVE essere predefinito ad almeno due ore.
È estremamente importante ricordare che i segmenti ACK che non contengono dati non sono trasmessi in modo affidabile da TCP. Pertanto, se viene implementato un meccanismo di keep-alive, NON DEVE interpretare il fallimento della risposta a una sonda specifica come una connessione morta.
Un'implementazione DOVREBBE inviare un segmento keep-alive senza dati; tuttavia, PUÒ essere configurabile per inviare un segmento keep-alive contenente un byte spazzatura, per compatibilità con implementazioni TCP errate.
DISCUSSIONE:
Un meccanismo di "keep-alive" sonda periodicamente l'altra estremità di una connessione quando la connessione è altrimenti inattiva, anche quando non ci sono dati da inviare. La specifica TCP non include un meccanismo di keep-alive perché potrebbe: (1) interrompere connessioni perfettamente buone durante fallimenti Internet transitori; (2) consumare larghezza di banda non necessaria ("se nessuno sta usando la connessione, chi se ne preoccupa se è ancora buona?"); e (3) costare denaro per un percorso Internet che addebita per pacchetto.
Tuttavia, alcune implementazioni TCP hanno incluso un meccanismo di keep-alive. Per confermare che una connessione inattiva è ancora attiva, queste implementazioni inviano un segmento di sonda progettato per suscitare una risposta dal TCP peer. Tale segmento contiene generalmente SEG.SEQ = SND.NXT-1 e può o non può contenere un byte di dati spazzatura. Si noti che su una connessione silenziosa SND.NXT = RCV.NXT, quindi questo SEG.SEQ sarà fuori dalla finestra. Pertanto, la sonda fa sì che il ricevitore restituisca un segmento di riconoscimento, confermando che la connessione è ancora attiva. Se il peer ha abbandonato la connessione a causa di una partizione di rete o di un crash, risponderà con un RST invece di un segmento di riconoscimento.
Sfortunatamente, alcune implementazioni TCP mal progettate non rispondono a un segmento con SEG.SEQ = SND.NXT-1 a meno che il segmento non contenga dati. In alternativa, un'implementazione potrebbe determinare se un peer ha risposto correttamente ai pacchetti keep-alive senza byte di dati spazzatura.
Un meccanismo di keep-alive TCP dovrebbe essere invocato solo nelle applicazioni server che potrebbero altrimenti bloccarsi indefinitamente e consumare risorse inutilmente se un client si blocca o abbandona una connessione durante un fallimento di rete.
4.2.3.7 Multihoming TCP
Se un'applicazione su un host multi-homed non specifica l'indirizzo IP locale quando apre attivamente una connessione TCP, allora TCP DEVE chiedere al livello IP di selezionare un indirizzo IP locale prima di inviare il (primo) SYN. Vedere la funzione GET_SRCADDR() nella sezione 3.4.
In tutti gli altri momenti, un segmento precedente è stato inviato o ricevuto su questa connessione, e TCP DEVE utilizzare lo stesso indirizzo locale che è stato utilizzato in quei segmenti precedenti.
4.2.3.8 Opzioni IP
Quando le opzioni ricevute vengono passate dal livello IP a TCP, TCP DEVE ignorare le opzioni che non comprende.
Un TCP PUÒ supportare le opzioni Timestamp e Record Route.
Un'applicazione DEVE essere in grado di specificare un percorso di origine quando apre attivamente una connessione TCP, e questo DEVE avere la precedenza su un percorso di origine ricevuto in un datagramma.
Quando una connessione TCP viene APERta passivamente e arriva un pacchetto con un'opzione IP di percorso di origine completo (contenente un percorso di ritorno), TCP DEVE salvare il percorso di ritorno e utilizzarlo per tutti i segmenti inviati su quella connessione. Se arriva un percorso di origine diverso in un segmento successivo, l'impostazione successiva DOVREBBE sostituire quella precedente.
4.2.3.9 Messaggi ICMP
TCP DEVE agire su un messaggio di errore ICMP trasmesso dal livello IP, indirizzandolo alla connessione che ha creato l'errore. Le informazioni di demultiplexing necessarie possono essere trovate nell'intestazione IP contenuta nel messaggio ICMP.
-
Source Quench
TCP DEVE reagire a un Source Quench rallentando la trasmissione sulla connessione. La procedura RACCOMANDATA è che un Source Quench attivi un "slow start", come se fosse avvenuto un timeout di ritrasmissione.
-
Destination Unreachable -- codici 0, 1, 5
Poiché questi messaggi Unreachable indicano condizioni di errore soft, TCP NON DEVE abbandonare la connessione, e DOVREBBE rendere le informazioni disponibili all'applicazione.
DISCUSSIONE:
TCP potrebbe segnalare la condizione di errore soft direttamente al livello applicativo con una chiamata verso l'alto alla routine ERROR_REPORT, oppure potrebbe semplicemente notare il messaggio e segnalarlo all'applicazione solo se e quando la connessione TCP va in timeout.
-
Destination Unreachable -- codici 2-4
Queste sono condizioni di errore hard, quindi TCP DOVREBBE abbandonare la connessione.
-
Time Exceeded -- codici 0, 1
Questo dovrebbe essere gestito allo stesso modo dei codici Destination Unreachable 0, 1, 5 (vedere sopra).
-
Parameter Problem
Questo dovrebbe essere gestito allo stesso modo dei codici Destination Unreachable 0, 1, 5 (vedere sopra).
4.2.3.10 Validazione dell'indirizzo remoto (Remote Address Validation)
Un'implementazione TCP DEVE rifiutare come errore una chiamata OPEN locale per un indirizzo IP remoto non valido (ad esempio, un indirizzo broadcast o multicast).
Un SYN in ingresso con un indirizzo di origine non valido dovrebbe essere ignorato da TCP o dal livello IP (vedere la sezione 3.2.1.3).
Un'implementazione TCP DEVE rifiutare silenziosamente un segmento SYN in ingresso che è indirizzato a un indirizzo broadcast o multicast.
4.2.3.11 Modelli di traffico TCP (TCP Traffic Patterns)
IMPLEMENTAZIONE:
La specifica del protocollo TCP [TCP:1] dà all'implementatore molta libertà nella progettazione degli algoritmi che controllano il flusso di messaggi sulla connessione -- pacchettizzazione, gestione della finestra, invio di riconoscimenti, ecc. Queste decisioni di progettazione sono difficili perché un TCP deve adattarsi a un'ampia gamma di modelli di traffico. L'esperienza ha dimostrato che un implementatore TCP deve verificare il progetto su due modelli di traffico estremi:
-
Segmenti a singolo carattere (Single-character Segments)
Anche se il mittente utilizza l'algoritmo di Nagle, quando una connessione TCP trasporta traffico di login remoto attraverso una LAN a basso ritardo, il ricevitore otterrà generalmente un flusso di segmenti a singolo carattere. Se la modalità di echo del terminale remoto è attiva, il sistema del ricevitore farà generalmente eco a ciascun carattere man mano che viene ricevuto.
-
Trasferimento in blocco (Bulk Transfer)
Quando TCP viene utilizzato per un trasferimento in blocco, il flusso di dati dovrebbe essere composto (quasi) interamente da segmenti della dimensione dell'MSS effettivo. Sebbene TCP utilizzi uno spazio di numeri di sequenza con granularità di byte, nel modo di trasferimento in blocco il suo funzionamento dovrebbe essere come se TCP utilizzasse uno spazio di sequenza che conta solo i segmenti.
L'esperienza ha inoltre dimostrato che un singolo TCP può gestire in modo efficiente ed efficace questi due estremi.
Lo strumento più importante per verificare una nuova implementazione TCP è un programma di traccia dei pacchetti. C'è un grande volume di esperienza che mostra l'importanza di tracciare una varietà di modelli di traffico con altre implementazioni TCP e studiare attentamente i risultati.
4.2.3.12 Efficienza (Efficiency)
IMPLEMENTAZIONE:
Un'esperienza estesa ha portato ai seguenti suggerimenti per un'implementazione TCP efficiente:
(a) Non copiare i dati (Don't Copy Data)
Nel trasferimento di dati in blocco, i compiti principali intensivi di CPU sono la copia dei dati da un posto all'altro e il checksum dei dati. È vitale minimizzare il numero di copie dei dati TCP. Poiché il limite di velocità finale può essere il recupero dei dati attraverso il bus di memoria, può essere utile combinare la copia con il checksum, facendo entrambi con un singolo recupero dalla memoria.
(b) Creare manualmente la routine di checksum (Hand-Craft the Checksum Routine)
Una buona routine di checksum TCP è tipicamente da due a cinque volte più veloce di un'implementazione semplice e diretta della definizione. Spesso sono richiesti e consigliati grande cura e codifica astuta per rendere il codice del checksum "ultra-veloce". Vedere [TCP:10].
(c) Codificare per il caso comune (Code for the Common Case)
L'elaborazione del protocollo TCP può essere complicata, ma per la maggior parte dei segmenti ci sono solo poche semplici decisioni da prendere. L'elaborazione per segmento sarà notevolmente accelerata codificando la linea principale per minimizzare il numero di decisioni nel caso più comune.
4.2.4 INTERFACCIA TCP/LIVELLO APPLICATIVO (TCP/APPLICATION LAYER INTERFACE)
4.2.4.1 Rapporti asincroni (Asynchronous Reports)
CI DEVE essere un meccanismo per segnalare condizioni di errore TCP soft all'applicazione. Genericamente, assumiamo che questo prenda la forma di una routine ERROR_REPORT fornita dall'applicazione che può essere chiamata verso l'alto [INTRO:7] in modo asincrono dal livello di trasporto:
ERROR_REPORT(local connection name, reason, subreason)
La codifica precisa dei parametri reason e subreason non è specificata qui. Tuttavia, le condizioni che vengono segnalate in modo asincrono all'applicazione DEVONO includere:
- Messaggio di errore ICMP arrivato (vedere 4.2.3.9)
- Ritrasmissioni eccessive (vedere 4.2.3.5)
- Avanzamento del puntatore urgente (vedere 4.2.2.4).
Tuttavia, un programma applicativo che non desidera ricevere tali chiamate ERROR_REPORT DOVREBBE essere in grado di disabilitare efficacemente queste chiamate.
DISCUSSIONE:
Questi rapporti di errore generalmente riflettono errori soft che possono essere ignorati senza danno da molte applicazioni. È stato suggerito che queste chiamate di rapporto errori dovrebbero essere "off" per impostazione predefinita, ma questo non è richiesto.
4.2.4.2 Tipo di servizio (Type-of-Service)
Il livello applicativo DEVE essere in grado di specificare il Type-of-Service (TOS) per i segmenti inviati su una connessione. Non è richiesto, ma l'applicazione DOVREBBE essere in grado di cambiare il TOS durante la vita della connessione. TCP DOVREBBE trasmettere il valore TOS corrente senza modifica al livello IP, quando invia segmenti sulla connessione.
Il TOS sarà specificato indipendentemente in ciascuna direzione sulla connessione, in modo che l'applicazione ricevente specifichi il TOS utilizzato per i segmenti ACK.
TCP PUÒ trasmettere il TOS ricevuto più di recente all'applicazione.
DISCUSSIONE:
Alcune applicazioni (ad esempio, SMTP) cambiano la natura della loro comunicazione durante la vita di una connessione e vorrebbero quindi cambiare la specifica TOS.
Si noti anche che la chiamata OPEN specificata in RFC-793 include un parametro ("options") in cui il chiamante può specificare opzioni IP come percorso di origine, percorso di registrazione o timestamp.
4.2.4.3 Chiamata Flush (Flush Call)
Alcune implementazioni TCP hanno incluso una chiamata FLUSH, che svuoterà la coda di invio TCP di tutti i dati per i quali l'utente ha emesso chiamate SEND ma che sono ancora a destra della finestra di invio. Cioè, svuota il maggior numero possibile di dati di invio in coda senza perdere la sincronizzazione del numero di sequenza. Questo è utile per implementare la funzione "abort output" di Telnet.
4.2.4.4 Multihoming
L'interfaccia utente descritta nelle sezioni 2.7 e 3.8 di RFC-793 deve essere estesa per il multihoming. La chiamata OPEN DEVE avere un parametro opzionale:
OPEN( ... [local IP address,] ... )
per consentire la specifica dell'indirizzo IP locale.
DISCUSSIONE:
Alcune applicazioni basate su TCP devono specificare l'indirizzo IP locale da utilizzare per aprire una connessione particolare; FTP è un esempio.
IMPLEMENTAZIONE:
Una chiamata OPEN passiva con un parametro "indirizzo IP locale" specificato attenderà una richiesta di connessione in ingresso a quell'indirizzo. Se il parametro non è specificato, un OPEN passivo attenderà una richiesta di connessione in ingresso a qualsiasi indirizzo IP locale, quindi legherà l'indirizzo IP locale della connessione all'indirizzo particolare utilizzato.
Per una chiamata OPEN attiva, un parametro "indirizzo IP locale" specificato sarà utilizzato per aprire la connessione. Se il parametro non è specificato, il software di rete sceglierà un indirizzo IP locale appropriato (vedere la sezione 3.3.4.2) per la connessione.
4.2.5 RIEPILOGO DEI REQUISITI TCP (TCP REQUIREMENTS SUMMARY)
| Funzionalità | Sezione | DEVE | DOVREBBE | PUÒ | NON DEVE |
|---|---|---|---|---|---|
| Flag Push | |||||
| Aggregare o mettere in coda: dati non pushed | 4.2.2.2 | x | |||
| Mittente aggrega flag PSH consecutivi | 4.2.2.2 | x | |||
| Chiamata SEND può specificare PUSH | 4.2.2.2 | x | |||
| Se non: mittente bufferizza indefinitamente | 4.2.2.2 | x | |||
| Se non: PSH ultimo segmento | 4.2.2.2 | x | |||
| Notificare ALP ricevente di PSH | 4.2.2.2 | x | |||
| Inviare segmento dimensione max quando possibile | 4.2.2.2 | x | |||
| Finestra | |||||
| Trattare come numero senza segno | 4.2.2.3 | x | |||
| Trattare come numero 32-bit | 4.2.2.3 | x | |||
| Ridurre finestra da destra | 4.2.2.16 | x | |||
| Robusto contro riduzione finestra | 4.2.2.16 | x | |||
| Finestra ricezione chiusa indefinitamente | 4.2.2.17 | x | |||
| Mittente sonda finestra zero | 4.2.2.17 | x | |||
| Prima sonda dopo RTO | 4.2.2.17 | x | |||
| Backoff esponenziale | 4.2.2.17 | x | |||
| Consentire finestra rimanga zero indefinitamente | 4.2.2.17 | x | |||
| Mittente timeout connessione finestra zero | 4.2.2.17 | x | |||
| Dati urgenti | |||||
| Puntatore punta ultimo byte | 4.2.2.4 | x | |||
| Sequenza dati urgenti lunghezza arbitraria | 4.2.2.4 | x | |||
| Informare ALP in modo asincrono dati urgenti | 4.2.2.4 | x | |||
| ALP può sapere quanti dati urgenti in coda | 4.2.2.4 | x | |||
| Opzioni TCP | |||||
| Ricevere opzioni TCP in qualsiasi segmento | 4.2.2.5 | x | |||
| Ignorare opzioni non supportate | 4.2.2.5 | x | |||
| Gestire lunghezza opzione illegale | 4.2.2.5 | x | |||
| Implementare invio e ricezione opzione MSS | 4.2.2.6 | x | |||
| Inviare opzione MSS tranne quando 536 | 4.2.2.6 | x | |||
| Inviare sempre opzione MSS | 4.2.2.6 | x | |||
| MSS invio predefinito è 536 | 4.2.2.6 | x | |||
| Calcolare MSS invio effettivo | 4.2.2.6 | x | |||
| Checksum TCP | |||||
| Mittente genera checksum | 4.2.2.7 | x | |||
| Ricevitore verifica checksum | 4.2.2.7 | x | |||
| Utilizzare selezione ISN guidata da orologio | 4.2.2.9 | x | |||
| Apertura connessioni | |||||
| Supportare tentativi apertura simultanea | 4.2.2.10 | x | |||
| SYN-RCVD ricorda stato precedente | 4.2.2.11 | x | |||
| Chiamata Open passiva interferisce altri | 4.2.2.18 | x | |||
| Funzione: LISTEN simultanei stessa porta | 4.2.2.18 | x | |||
| Richiedere indirizzo IP origine per SYN se necessario | 4.2.3.7 | x | |||
| Altrimenti utilizzare indirizzo locale connessione | 4.2.3.7 | x | |||
| OPEN a indirizzo IP broadcast/multicast | 4.2.3.10 | x | |||
| Rifiutare silenziosamente segmento a broadcast/multicast | 4.2.3.10 | x | |||
| Chiusura connessioni | |||||
| RST può contenere dati | 4.2.2.12 | x | |||
| Informare applicazione connessione abortita | 4.2.2.13 | x | |||
| Chiusura connessione half-duplex | 4.2.2.13 | x | |||
| Inviare RST per indicare dati persi | 4.2.2.13 | x | |||
| Nello stato TIME-WAIT per 2×MSL secondi | 4.2.2.13 | x | |||
| Accettare SYN da stato TIME-WAIT | 4.2.2.13 | x | |||
| Ritrasmissioni | |||||
| Algoritmo slow start di Jacobson | 4.2.2.15 | x | |||
| Algoritmo congestion avoidance di Jacobson | 4.2.2.15 | x | |||
| Ritrasmettere con stessa ident IP | 4.2.2.15 | x | |||
| Algoritmo di Karn | 4.2.3.1 | x | |||
| Algoritmo stima RTO di Jacobson | 4.2.3.1 | x | |||
| Backoff esponenziale | 4.2.3.1 | x | |||
| Calcolo RTO SYN uguale a dati | 4.2.3.1 | x | |||
| Valori iniziali e limiti raccomandati | 4.2.3.1 | x | |||
| Generazione ACK | |||||
| Mettere in coda segmenti fuori sequenza | 4.2.2.20 | x | |||
| Elaborare intera coda prima invio ACK | 4.2.2.20 | x | |||
| Inviare ACK per segmento fuori sequenza | 4.2.2.21 | x | |||
| ACK ritardati | 4.2.3.2 | x | |||
| Ritardo < 0,5 secondi | 4.2.3.2 | x | |||
| ACK ogni 2° segmento dimensione completa | 4.2.3.2 | x | |||
| Algoritmo prevenzione SWS ricevitore | 4.2.3.3 | x | |||
| Invio dati | |||||
| TTL configurabile | 4.2.2.19 | x | |||
| Algoritmo prevenzione SWS mittente | 4.2.3.4 | x | |||
| Algoritmo di Nagle | 4.2.3.4 | x | |||
| Applicazione può disabilitare algoritmo Nagle | 4.2.3.4 | x | |||
| Fallimenti connessione | |||||
| Notifica IP negativa su R1 retrans | 4.2.3.5 | x | |||
| Chiudere connessione su R2 retrans | 4.2.3.5 | x | |||
| ALP può impostare R2 | 4.2.3.5 | x | |||
Informare ALP R1≤retrans<R2 | 4.2.3.5 | x | |||
| Valori raccomandati R1, R2 | 4.2.3.5 | x | |||
| Stesso meccanismo per SYN | 4.2.3.5 | x | |||
| R2 almeno 3 minuti per SYN | 4.2.3.5 | x | |||
| Invio pacchetti keep-alive | 4.2.3.6 | x | |||
| Applicazione può richiedere | 4.2.3.6 | x | |||
| Predefinito "off" | 4.2.3.6 | x | |||
| Inviare solo quando inattivo per intervallo | 4.2.3.6 | x | |||
| Intervallo configurabile | 4.2.3.6 | x | |||
| Predefinito almeno 2 ore | 4.2.3.6 | x | |||
| Tolerante ACK persi | 4.2.3.6 | x | |||
| Opzioni IP | |||||
| Ignorare opzioni TCP non comprende | 4.2.3.8 | x | |||
| Supportare timestamp | 4.2.3.8 | x | |||
| Supportare record route | 4.2.3.8 | x | |||
| Percorso origine | |||||
| ALP può specificare | 4.2.3.8 | x | |||
| Sostituire percorso origine in datagramma | 4.2.3.8 | x | |||
| Costruire percorso ritorno da percorso origine | 4.2.3.8 | x | |||
| Percorso origine successivo sostituisce | 4.2.3.8 | x | |||
| Ricezione messaggi ICMP da IP | 4.2.3.9 | x | |||
| Dest Unreachable(0,1,5)→informare ALP | 4.2.3.9 | x | |||
| Dest Unreachable(0,1,5)→non abbandonare connessione | 4.2.3.9 | x | |||
| Dest Unreachable(2-4)→abbandonare connessione | 4.2.3.9 | x | |||
| Source Quench→slow start | 4.2.3.9 | x | |||
| Time Exceeded→dire ALP, non abbandonare | 4.2.3.9 | x | |||
| Param Problem→dire ALP, non abbandonare | 4.2.3.9 | x | |||
| Validazione indirizzo | |||||
| Rifiutare chiamata OPEN indirizzo IP non valido | 4.2.3.10 | x | |||
| Rifiutare SYN indirizzo IP non valido | 4.2.3.10 | x | |||
| Rifiutare silenziosamente SYN broadcast/multicast | 4.2.3.10 | x | |||
| Servizi interfaccia TCP/ALP | |||||
| Meccanismo rapporto errori | 4.2.4.1 | x | |||
| ALP può disabilitare routine rapporto errori | 4.2.4.1 | x | |||
| ALP può specificare TOS invio | 4.2.4.2 | x | |||
| Trasmesso senza modifica a IP | 4.2.4.2 | x | |||
| ALP può cambiare TOS durante connessione | 4.2.4.2 | x | |||
| Trasmettere TOS ricevuto a ALP | 4.2.4.2 | x | |||
| Chiamata FLUSH | 4.2.4.3 | x | |||
| Parametro indirizzo IP locale opzionale in OPEN | 4.2.4.4 | x |
NOTE:
(1) "ALP" significa Programma del Livello Applicativo (Application-Layer Program).