In sez.~\ref{sec:file_shared_access} abbiamo preso in esame le modalità in cui
un sistema unix-like gestisce l'accesso concorrente ai file da parte di
processi diversi. In quell'occasione si è visto come, con l'eccezione dei file
-aperti in \itindex{append~mode} \textit{append mode}, quando più processi
-scrivono contemporaneamente sullo stesso file non è possibile determinare la
-sequenza in cui essi opereranno.
+aperti in \textit{append mode}, quando più processi scrivono
+contemporaneamente sullo stesso file non è possibile determinare la sequenza
+in cui essi opereranno.
Questo causa la possibilità di una \itindex{race~condition} \textit{race
condition}; in generale le situazioni più comuni sono due: l'interazione fra
pur non essendo proprietari del file (dal kernel
2.4).\\
\const{CAP\_LINUX\_IMMUTABLE}& Impostare sui file gli attributi
- \textit{immutable} e \itindex{append~mode}
- \textit{append-only} (vedi
+ \textit{immutable} e \textit{append-only} (vedi
sez.~\ref{sec:file_perm_overview}) se
supportati.\\
\const{CAP\_MKNOD} & Creare \index{file!di~dispositivo} file di
operazioni di lettura e scrittura avvengono a partire da questa posizione che
viene automaticamente spostata in avanti del numero di byte letti o scritti.
-In genere, a meno di non avere richiesto la modalità \itindex{append~mode} di
-\textit{append} con \const{O\_APPEND}, questa posizione viene impostata a zero
-all'apertura del file. È possibile impostarla ad un valore qualsiasi con la
-funzione di sistema \funcd{lseek}, il cui prototipo è:
+In genere, a meno di non avere richiesto la modalità di \textit{append} con
+\const{O\_APPEND}, questa posizione viene impostata a zero all'apertura del
+file. È possibile impostarla ad un valore qualsiasi con la funzione di sistema
+\funcd{lseek}, il cui prototipo è:
\begin{funcproto}{
\fhead{sys/types.h}
la successiva scrittura avvenga alla fine del file, infatti se questo è stato
aperto anche da un altro processo che vi ha scritto, la fine del file può
essersi spostata, ma noi scriveremo alla posizione impostata in precedenza
-(questa è una potenziale sorgente di \itindex{race~condition} \textit{race
- condition}, vedi sez.~\ref{sec:file_shared_access}).
+(questa è una potenziale sorgente di \textit{race condition}, vedi
+sez.~\ref{sec:file_shared_access}).
Non tutti i file supportano la capacità di eseguire una \func{lseek}, in
questo caso la funzione ritorna l'errore \errcode{ESPIPE}. Questo, oltre che
Come nel caso di \func{read} la funzione tenta di scrivere \param{count} byte
a partire dalla posizione corrente nel file e sposta automaticamente la
posizione in avanti del numero di byte scritti. Se il file è aperto in
-modalità \itindex{append~mode} \const{O\_APPEND} i dati vengono sempre scritti
+modalità \textit{append} con \const{O\_APPEND} i dati vengono sempre scritti
alla fine del file. Lo standard POSIX richiede che i dati scritti siano
immediatamente disponibili ad una \func{read} chiamata dopo che la
\func{write} che li ha scritti è ritornata; ma dati i meccanismi di caching
\textit{acknowlegment}, all'arrivo sarà comunque possibile riordinare i dati e
scartare i duplicati.
+\itindbeg{advertised~window}
+
Il protocollo provvede anche un controllo di flusso (\textit{flow control}),
cioè specifica sempre all'altro capo della trasmissione quanti dati può
-ricevere tramite una \itindex{advertised~window} \textit{advertised window}
-(letteralmente ``\textsl{finestra annunciata}''), che indica lo spazio
-disponibile nel buffer di ricezione, cosicché nella trasmissione non vengano
-inviati più dati di quelli che possono essere ricevuti.
+ricevere tramite una \textit{advertised window} (letteralmente
+``\textsl{finestra annunciata}''), che indica lo spazio disponibile nel buffer
+di ricezione, cosicché nella trasmissione non vengano inviati più dati di
+quelli che possono essere ricevuti.
Questa finestra cambia dinamicamente diminuendo con la ricezione dei dati dal
socket ed aumentando con la lettura di quest'ultimo da parte
ciò per cui nulla impedisce che vengano trasmessi pacchetti ad un ritmo che il
ricevente non può sostenere.
+\itindend{advertised~window}
+
Infine attraverso TCP la trasmissione è sempre bidirezionale (in inglese si
dice che è \textit{full-duplex}). È cioè possibile sia trasmettere che
ricevere allo stesso tempo, il che comporta che quanto dicevamo a proposito
\const{TCP\_DEFER\_ACCEPT}&$\bullet$&$\bullet$& &\texttt{int}&
Ritorna da \func{accept} solo in presenza di dati.\\
\const{TCP\_WINDOW\_CLAMP}&$\bullet$&$\bullet$& &\texttt{int}&
- Valore della \itindex{advertised~window} \textit{advertised window}.\\
+ Valore della \textit{advertised window}.\\
\const{TCP\_INFO} &$\bullet$& & &\struct{tcp\_info}&
Restituisce informazioni sul socket.\\
\const{TCP\_QUICKACK} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
\item[\const{TCP\_WINDOW\_CLAMP}] con questa opzione si legge o si imposta
alla dimensione specificata, in byte, il valore dichiarato della
- \itindex{advertised~window} \textit{advertised window} (vedi
- sez.~\ref{sec:tcp_protocol_xxx}). Il kernel impone comunque una dimensione
- minima pari a \texttt{SOCK\_MIN\_RCVBUF/2}. Questa opzione non deve essere
- utilizzata in codice che vuole essere portabile.
+ \textit{advertised window} (vedi sez.~\ref{sec:tcp_protocol_xxx}). Il kernel
+ impone comunque una dimensione minima pari a \texttt{SOCK\_MIN\_RCVBUF/2}.
+ Questa opzione non deve essere utilizzata in codice che vuole essere
+ portabile.
\begin{figure}[!htb]
\footnotesize \centering
quando si è sicuri che non è possibile ottimizzare il server in modo che sia
in grado di accettare connessioni più rapidamente.
-\item[\sysctlrelfile{net/ipv4}{tcp\_adv\_win\_scale}] indica al kernel
- quale frazione del buffer associato ad un socket\footnote{quello impostato
- con \sysctlrelfile{net/ipv4}{tcp\_rmem}.} deve essere utilizzata
- per la finestra del protocollo TCP\footnote{in sostanza il valore che
- costituisce la \itindex{advertised~window} \textit{advertised window}
- annunciata all'altro capo del socket.} e quale come buffer applicativo per
- isolare la rete dalle latenze dell'applicazione. Prende un valore intero
- che determina la suddetta frazione secondo la formula
+\item[\sysctlrelfile{net/ipv4}{tcp\_adv\_win\_scale}] indica al kernel quale
+ frazione del buffer associato ad un socket\footnote{quello impostato con
+ \sysctlrelfile{net/ipv4}{tcp\_rmem}.} deve essere utilizzata per la
+ finestra del protocollo TCP\footnote{in sostanza il valore che costituisce
+ la \textit{advertised window} annunciata all'altro capo del socket.} e
+ quale come buffer applicativo per isolare la rete dalle latenze
+ dell'applicazione. Prende un valore intero che determina la suddetta
+ frazione secondo la formula
$\texttt{buffer}/2^\texttt{tcp\_adv\_win\_scale}$ se positivo o con
$\texttt{buffer}-\texttt{buffer}/2^\texttt{tcp\_adv\_win\_scale}$ se
negativo. Il default è 2 che significa che al buffer dell'applicazione
Quando si attiva la contabilità, il file che si indica deve esistere; esso
verrà aperto in sola scrittura e le informazioni verranno registrate in
-\itindex{append~mode} \textit{append} in coda al file tutte le volte che un
-processo termina. Le informazioni vengono salvate in formato binario, e
-corrispondono al contenuto della apposita struttura dati definita all'interno
-del kernel.
+\textit{append} in coda al file tutte le volte che un processo termina. Le
+informazioni vengono salvate in formato binario, e corrispondono al contenuto
+della apposita struttura dati definita all'interno del kernel.
Il funzionamento di \func{acct} viene inoltre modificato da uno specifico
parametro di sistema, modificabile attraverso \sysctlfile{kernel/acct} (o
sez.~\ref{sec:sock_tcp_udp_options}).
\item \textit{window scale option}, il protocollo TCP implementa il controllo
- di flusso attraverso una \itindex{advertised~window} \textit{advertised
- window} (la ``\textsl{finestra annunciata}'', vedi
- sez.~\ref{sec:tcp_protocol_xxx}) con la quale ciascun capo della
- comunicazione dichiara quanto spazio disponibile ha in memoria per i dati.
- Questo è un numero a 16 bit dell'header, che così può indicare un massimo di
- 65535 byte;\footnote{in Linux il massimo è 32767 per evitare problemi con
- alcune implementazioni che usano l'aritmetica con segno per implementare
- lo stack TCP.} ma alcuni tipi di connessione come quelle ad alta velocità
- (sopra i 45Mbit/sec) e quelle che hanno grandi ritardi nel cammino dei
- pacchetti (come i satelliti) richiedono una finestra più grande per poter
- ottenere il massimo dalla trasmissione. Per questo esiste questa opzione che
- indica un fattore di scala da applicare al valore della
- \itindex{advertised~window} finestra annunciata\footnote{essendo una nuova
- opzione per garantire la compatibilità con delle vecchie implementazioni
- del protocollo la procedura che la attiva prevede come negoziazione che
- l'altro capo della connessione riconosca esplicitamente l'opzione
- inserendola anche lui nel suo SYN di risposta dell'apertura della
- connessione.} per la connessione corrente (espresso come numero di bit cui
- spostare a sinistra il valore della finestra annunciata inserito nel
- pacchetto). Con Linux è possibile indicare al kernel di far negoziare il
- fattore di scala in fase di creazione di una connessione tramite la
- \textit{sysctl} \itindex{TCP~window~scaling} \texttt{tcp\_window\_scaling}
- (vedi sez.~\ref{sec:sock_ipv4_sysctl}).\footnote{per poter usare questa
+ di flusso attraverso una \textit{advertised window} (la ``\textsl{finestra
+ annunciata}'', vedi sez.~\ref{sec:tcp_protocol_xxx}) con la quale ciascun
+ capo della comunicazione dichiara quanto spazio disponibile ha in memoria
+ per i dati. Questo è un numero a 16 bit dell'header, che così può indicare
+ un massimo di 65535 byte;\footnote{in Linux il massimo è 32767 per evitare
+ problemi con alcune implementazioni che usano l'aritmetica con segno per
+ implementare lo stack TCP.} ma alcuni tipi di connessione come quelle ad
+ alta velocità (sopra i 45Mbit/sec) e quelle che hanno grandi ritardi nel
+ cammino dei pacchetti (come i satelliti) richiedono una finestra più grande
+ per poter ottenere il massimo dalla trasmissione. Per questo esiste questa
+ opzione che indica un fattore di scala da applicare al valore della finestra
+ annunciata\footnote{essendo una nuova opzione per garantire la compatibilità
+ con delle vecchie implementazioni del protocollo la procedura che la
+ attiva prevede come negoziazione che l'altro capo della connessione
+ riconosca esplicitamente l'opzione inserendola anche lui nel suo SYN di
+ risposta dell'apertura della connessione.} per la connessione corrente
+ (espresso come numero di bit cui spostare a sinistra il valore della
+ finestra annunciata inserito nel pacchetto). Con Linux è possibile indicare
+ al kernel di far negoziare il fattore di scala in fase di creazione di una
+ connessione tramite la \textit{sysctl} \itindex{TCP~window~scaling}
+ \texttt{tcp\_window\_scaling} (vedi
+ sez.~\ref{sec:sock_ipv4_sysctl}).\footnote{per poter usare questa
funzionalità è comunque necessario ampliare le dimensioni dei buffer di
ricezione e spedizione, cosa che può essere fatta sia a livello di sistema
con le opportune \textit{sysctl} (vedi sez.~\ref{sec:sock_ipv4_sysctl})
sempre attivo il campo \texttt{ack}, seguito dal numero di sequenza per il
quale si da il ricevuto; quest'ultimo, a partire dal terzo pacchetto, viene
espresso in forma relativa per maggiore compattezza. Il campo \texttt{win} in
-ogni riga indica la \itindex{advertised~window} \textit{advertised window} di
-cui parlavamo in sez.~\ref{sec:TCP_TCP_opt}. Allora si può verificare
-dall'output del comando come venga appunto realizzata la sequenza di pacchetti
-descritta in sez.~\ref{sec:TCP_conn_cre}: prima viene inviato dal client un
-primo pacchetto con il SYN che inizia la connessione, a cui il server risponde
-dando il ricevuto con un secondo pacchetto, che a sua volta porta un SYN, cui
-il client risponde con un il terzo pacchetto di ricevuto.
+ogni riga indica la \textit{advertised window} di cui parlavamo in
+sez.~\ref{sec:TCP_TCP_opt}. Allora si può verificare dall'output del comando
+come venga appunto realizzata la sequenza di pacchetti descritta in
+sez.~\ref{sec:TCP_conn_cre}: prima viene inviato dal client un primo pacchetto
+con il SYN che inizia la connessione, a cui il server risponde dando il
+ricevuto con un secondo pacchetto, che a sua volta porta un SYN, cui il client
+risponde con un il terzo pacchetto di ricevuto.
Ritorniamo allora alla nostra sessione con il servizio echo: dopo le tre righe
del \itindex{three~way~handshake} \textit{three way handshake} non avremo