Aggiunti alcuni riferimenti, documentate le costanti IPPORT_RESERVED e
authorSimone Piccardi <piccardi@gnulinux.it>
Sun, 24 Apr 2005 17:07:24 +0000 (17:07 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sun, 24 Apr 2005 17:07:24 +0000 (17:07 +0000)
IPPORT_USERRESERVED, finita la trattazione di SO_REUSEADDR e iniziata quella
di SO_LINGER, inserita una nuova sezione sulle opzioni dei socket piu'
significative, aggiunta quanche informazione sulle opzioni di IPv4.

listati/hand_sigchild.c
listati/linger.h [new file with mode: 0644]
prochand.tex
session.tex
signal.tex
sockctrl.tex
tcpsock.tex

index f55168f8aea0b153151696a884f56afc108ab2fc..aa8d4d4e55dca0db68b74db5b1aaaf14edbb9366 100644 (file)
@@ -9,9 +9,6 @@ void HandSigCHLD(int sig)
     do {
         errno = 0;
         pid = waitpid(WAIT_ANY, &status, WNOHANG);
-        if (pid > 0) {
-            debug("child %d terminated with status %x\n", pid, status);
-        }
     } while (pid > 0);
     /* restore errno value */
     errno = errno_save;
diff --git a/listati/linger.h b/listati/linger.h
new file mode 100644 (file)
index 0000000..fe9e9df
--- /dev/null
@@ -0,0 +1,5 @@
+struct linger
+{
+    int l_onoff;                /* Nonzero to linger on close.  */
+    int l_linger;               /* Time to linger (in seconds). */
+}
index 9be38cc84eafd92a8f8b4464be3ade84dcc8b4d2..6bdbb5a97966c1d3813956ad06829512055854ab 100644 (file)
@@ -681,7 +681,7 @@ eseguite alla chiusura di un processo 
   sez.~\ref{sec:sig_sigchld});
 \item se il processo è un leader di sessione ed il suo terminale di controllo
   è quello della sessione viene mandato un segnale di \const{SIGHUP} a tutti i
-  processi del gruppo di foreground e il terminale di controllo viene
+  processi del gruppo di \textit{foreground} e il terminale di controllo viene
   disconnesso (vedi sez.~\ref{sec:sess_ctrl_term});
 \item se la conclusione di un processo rende orfano un \textit{process
     group} ciascun membro del gruppo viene bloccato, e poi gli vengono
@@ -771,10 +771,10 @@ informazione, non pi
 completamente conclusa.
 
 Possiamo utilizzare il nostro programma di prova per analizzare anche questa
-condizione: lanciamo il comando \cmd{forktest} in background, indicando al
-processo padre di aspettare 10 secondi prima di uscire; in questo caso, usando
-\cmd{ps} sullo stesso terminale (prima dello scadere dei 10 secondi)
-otterremo:
+condizione: lanciamo il comando \cmd{forktest} in \textit{background} (vedi
+sez.~\ref{sec:sess_job_control}), indicando al processo padre di aspettare 10
+secondi prima di uscire; in questo caso, usando \cmd{ps} sullo stesso
+terminale (prima dello scadere dei 10 secondi) otterremo:
 
 \footnotesize
 \begin{verbatim}
index c042e915bda6d45b3749053911df2f7709964a07..ae8322ece30f1d68dbabfcd79af209315267939a 100644 (file)
@@ -60,11 +60,11 @@ sez.~\ref{sec:sess_login}).
 
 Siccome la shell è collegata ad un solo terminale, che viene usualmente
 chiamato \textsl{terminale di controllo}, (vedi sez.~\ref{sec:sess_ctrl_term})
-un solo comando alla volta (quello che viene detto in \textit{foreground}),
-potrà scrivere e leggere dal terminale. La shell però può eseguire anche più
-comandi in contemporanea, mandandoli in \textit{background} (aggiungendo una
-\cmd{\&} alla fine del comando), nel qual caso essi saranno eseguiti senza
-essere collegati al terminale.
+un solo comando alla volta (quello che viene detto in \textit{foreground} o in
+\textsl{primo piano}), potrà scrivere e leggere dal terminale. La shell però
+può eseguire, aggiungendo una \cmd{\&} alla fine del comando, più programmi in
+contemporanea, mandandoli in \textit{background} (o \textsl{sullo sfondo}),
+nel qual caso essi saranno eseguiti senza essere collegati al terminale.
 
 Si noti come si sia parlato di comandi e non di programmi o processi; fra le
 funzionalità della shell infatti c'è anche quella di consentire di concatenare
@@ -291,8 +291,8 @@ dal quale ricevono gli eventuali segnali da tastiera.
 
 A tale scopo lo standard POSIX.1 prevede che ad ogni sessione possa essere
 associato un terminale di controllo; in Linux questo viene realizzato
-mantenendo fra gli attributi di ciascun processo anche qual è il suo terminale
-di controllo. \footnote{Lo standard POSIX.1 non specifica nulla riguardo
+mantenendo fra gli attributi di ciascun processo anche qual'è il suo terminale
+di controllo.\footnote{Lo standard POSIX.1 non specifica nulla riguardo
   l'implementazione; in Linux anch'esso viene mantenuto nella solita struttura
   \struct{task\_struct}, nel campo \var{tty}.}  In generale ogni processo
 eredita dal padre, insieme al \acr{pgid} e al \acr{sid} anche il terminale di
index 2e24f3653f104d5d55f977095553a4fed6bf5cd9..df3727cb06101d026517a13a095f5488570eee6b 100644 (file)
@@ -1397,12 +1397,6 @@ di sez.~\ref{sec:proc_termination}, invocando \cmd{forktest} con l'opzione
 gestore di \const{SIGCHLD}) potremo verificare che non si ha più la creazione
 di zombie\index{zombie}.
 
-%  è pertanto
-% naturale usare un esempio che ci permette di concludere la trattazione della
-% terminazione dei processi.
-% In questo caso si è tratterà di illustrare un esempio relativo ad un
-% gestore per che è previsto ritornare,
-
 \begin{figure}[!htb]
   \footnotesize  \centering
   \begin{minipage}[c]{15cm}
index 1d7df3884d657ecfd1e8cbc7a277afaeafc23156..7e8a5b611baff469dd1c6aaf389b0ed783d03603 100644 (file)
@@ -2066,66 +2066,27 @@ usato per \param{optval} ed una breve descrizione del significato delle
 singole opzioni sulla sesta.
 
 
-Dato che le descrizioni di tab.~\ref{tab:sock_opt_socklevel} sono estremamente
-sommarie, vale la pena entrare in dettagli maggiori; questo ci consentirà
-anche di trattare i vari casi particolari, dato che nonostante queste opzioni
-siano indicate al livello generico, alcune di esse han senso solo per alcuni
-tipi di socket. L'elenco dettagliato del significato di ciascuna di esse è
-allora il seguente:
+Questo ci consentirà anche
+di trattare approfonditamente alcune opzioni che, nonostante siano
+classificate fra quelle generiche, hanno un significato effettivo solo per
+alcuni tipi di socket.TCP/IP.  L'elenco dettagliato del significato delle
+opzioni generiche dei socket è allora il seguente:
+
+
+Le descrizioni delle opzioni presenti in tab.~\ref{tab:sock_opt_socklevel}
+sono estremamente sommarie, è perciò necessario fornire un po' più di
+informazioni; alcune opzioni comunque hanno una notevole rilevanza nella
+gestione dei socket, e pertanto il loro utilizzo sarà approfondito
+separatamente in sez.~\ref{sec:sock_options_main}. Quello che segue pertanto è
+soltanto un elenco più dettagliato di quanto scritto in
+tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni:
 \begin{basedescript}{\desclabelwidth{2.5cm}\desclabelstyle{\nextlinelabel}}
-\item[\const{SO\_KEEPALIVE}] una connessione può restare attiva se non viene
-  effettuato alcun traffico su di essa; in certi casi però può essere utile
-  controllarne lo stato per accorgersi di eventuali problemi. Per questo, se
-  si imposta questa opzione, è cura del kernel inviare degli appositi messaggi
-  sulla rete (detti appunto \textit{keep-alive}) per verificare se la
-  connessione è attiva.  L'opzione funziona soltanto con socket che supportino
-  le connessioni (non ha senso per socket UDP ad esempio), ed utilizza per
-  \param{optval} un intero usato come valore logico. 
-
-  L'opzione si applica principalmente ai socket TCP.  Con le impostazioni di
-  default (che sono riprese da BSD) Linux emette un messaggio di
-  \textit{keep-alive} verso l'altro capo della connessione se questa è rimasta
-  senza traffico per più di due ore. Se è tutto a posto il messaggio viene
-  ricevuto e verrà emesso un segmento ACK di risposta, alla cui ricezione
-  ripartirà un'altro ciclo di attesa per altre due ore di inattività; tutto
-  ciò viene effettuato dal kernel e le applicazioni non riceveranno nessun
-  dato. 
-
-  In caso di problemi invece si possono avere i due casi già illustrati in
-  sez.~\ref{sec:TCP_conn_crash} per il caso di terminazione prococe del
-  server: il primo è quello in cui la macchina remota è caduta ed è stata
-  riavviata, per cui dopo il riavvio la connessione non viene più
-  riconosciuta,\footnote{si ricordi che un normale riavvio non ha questo
-    effetto, in quanto si passa per la chiusura del processo, che chiude anche
-    il socket inviando un segmento FIN all'altro capo della connessione.} e si
-  otterrà come risposta un RST. In tal caso il socket viene chiuso dopo aver
-  impostato un errore \errcode{ECONNRESET}.
-
-  Se invece non viene ricevuta nessuna risposta (indice che la macchina non è
-  più raggiungibile) l'emissione dei messaggi viene ripetuta ad intervalli di
-  75 secondi ad un massimo di 9 volte\footnote{entrambi questi valori possono
-    essere opportunamente modificati con gli opportuni parametri illustrati in
-    sez.~\ref{sec:sock_sysctl}, si tenga presente che però questo vale a
-    livello di kernel ed i valori saranno applicati a \textsl{tutti} i
-    socket.} (per un totale di 11 minuti e 15 secondi) dopo di che, se non si
-  è ricevuta nessuna risposta, il socket viene chiuso dopo aver impostato un
-  errore di \errcode{ETIMEDOUT}. Se invece si riceve in risposta ad uno di
-  questi messaggi un pacchetto ICMP di destinazione irraggiungibile, verrà
-  restituito l'errore corrispondente. 
-
-  In generale questa opzione serve per individuare una caduta della
-  connessione,\footnote{il crash di un processo di nuovo comporta la chiusura
-    di tutti i file che aveva aperti e la relativa emissione degli opportuni
-    segmenti FIN nel caso dei socket.} e viene usata sui server per evitare di
-  mantenere impegnate le risorse dedicate a trattare delle connessioni in
-  realtà terminate.  Abilitandola le connessioni effettivamente terminate
-  vengono chiuse ed una \func{select} potrà rilevare la conclusione delle
-  stesse e ricevere il relativo errore. Si tenga però presente che non si ha
-  la certezza assoluta che un errore di \errcode{ETIMEDOUT} corrisponda ad una
-  reale conclusione della connessione, il problema potrebbe essere dovuto ad
-  un problema di routing che perduri per un tempo maggiore di quello impiegato
-  nei vari tentativi di ritrasmissione del \textit{keep-alive}. 
-
+\item[\const{SO\_KEEPALIVE}] questa opzione abilita un meccanismo di verifica
+  della persistenza di una connessione associata al socket (ed è pertanto
+  effettiva solo sui socket che supportano le connessioni, ed è usata
+  principalmente con il TCP). L'opzione utilizza per \param{optval} un intero
+  usato come valore logico. Maggiori dettagli sul suo funzionamento sono
+  forniti in sez.~\ref{sec:sock_options_main}.
 
 \item[\const{SO\_OOBINLINE}] se questa opzione viene abilitata i dati
   \textit{out-of-band} vengono inviati direttamente nel flusso di dati del
@@ -2205,9 +2166,10 @@ allora il seguente:
   state rimosse con il passaggio al 2.2; è consigliato correggere i programmi
   piuttosto che usare questa funzione. 
 
-\item[\const{SO\_PASSCRED}] questa opzione abilita sui socket unix-domain la
-  ricezione dei messaggi di controllo di tipo \const{SCM\_CREDENTIALS}. Prende
-  come \param{optval} un intero usato come valore logico. 
+\item[\const{SO\_PASSCRED}] questa opzione abilita sui socket unix-domain
+  (vedi sez.~\ref{sec:unix_socket}) la ricezione dei messaggi di controllo di
+  tipo \const{SCM\_CREDENTIALS}. Prende come \param{optval} un intero usato
+  come valore logico.
 
 \item[\const{SO\_PEERCRED}] questa opzione restituisce le credenziali del
   processo remoto connesso al socket; l'opzione è disponibile solo per socket
@@ -2217,11 +2179,10 @@ allora il seguente:
 
 \item[\const{SO\_BINDTODEVICE}] questa opzione permette di \textsl{legare} il
   socket ad una particolare interfaccia, in modo che esso possa ricevere ed
-  inviare pacchetti solo su quella. L'opzione richiede per
-  \param{optval} il puntatore ad una stringa contenente il nome
-  dell'interfaccia (ad esempio \texttt{eth0}); se si utilizza una stringa
-  nulla o un valore nullo per \param{optlen} si rimuove un precedente
-  collegamento. 
+  inviare pacchetti solo su quella. L'opzione richiede per \param{optval} il
+  puntatore ad una stringa contenente il nome dell'interfaccia (ad esempio
+  \texttt{eth0}); utilizzando una stringa nulla o un valore nullo per
+  \param{optlen} si può rimuovere un precedente collegamento.
 
   Il nome della interfaccia deve essere specificato con una stringa terminata
   da uno zero e di lunghezza massima pari a \const{IFNAMSIZ}; l'opzione è
@@ -2229,7 +2190,6 @@ allora il seguente:
   famiglia \const{AF\_INET}; non è invece supportata per i \textit{packet
     socket} (vedi sez.~\ref{cha:advanced_socket_xxx}). 
 
-
 \item[\const{SO\_DEBUG}] questa opzione abilita il debugging delle operazioni
   dei socket; l'opzione utilizza per \param{optval} un intero usato come
   valore logico, e può essere utilizzata solo da un processo con i privilegi
@@ -2250,70 +2210,14 @@ allora il seguente:
     programma, \cmd{trpt}.} 
 
 \item[\const{SO\_REUSEADDR}] questa opzione permette di eseguire la funzione
-  \func{bind} su indirizzi locali che siano già in uso; l'opzione utilizza per
-  \param{optval} un intero usato come valore logico.  Questa opzione modifica
-  il comportamento normale dell'interfaccia dei socket che fa fallire
-  l'esecuzione della funzione \func{bind} con un errore di
+  \func{bind} su indirizzi locali che siano già in uso da altri socket;
+  l'opzione utilizza per \param{optval} un intero usato come valore logico.
+  Questa opzione modifica il comportamento normale dell'interfaccia dei socket
+  che fa fallire l'esecuzione della funzione \func{bind} con un errore di
   \errcode{EADDRINUSE} quando l'indirizzo locale\footnote{più propriamente il
     controllo viene eseguito sulla porta.} è già in uso da parte di un altro
-  socket. 
-
-  Come Stevens sottolinea in \cite{UNP1} si distinguono quattro casi per
-  l'utilizzo di questa opzione; il primo è quello in cui un server è terminato
-  ma esistono ancora dei processi figli che mantengono attiva almeno una
-  connessione remota che utilizza l'indirizzo locale. Quando si riavvia il
-  server questo viene bloccato sulla chiamata a \func{bind} dato che la porta
-  è ancora utilizzata in una connessione esistente.\footnote{questa è una
-    delle domande più frequenti sui newsgroup dedicati allo sviluppo, in
-    quanto è piuttosto comune in questa situazione quando si sta sviluppando
-    un server che si ferma e si riavvia in continuazione.}  Inoltre se si usa
-  il protocollo TCP questo può avvenire anche dopo che l'ultimo processo
-  figlio è terminato, dato che la connessione può restare attiva anche dopo la
-  chiusura del socket mantenendosi nello stato \texttt{TIME\_WAIT}. 
-
-  Usando \const{SO\_REUSEADDR} fra la chiamata a \func{socket} e quella a
-  \func{bind} si consente a quest'ultima di avere comunque successo anche se
-  la connessione è attiva (o nello stato \texttt{TIME\_WAIT}). È bene però
-  ricordare (si riveda quanto detto in sez.~\ref{sec:TCP_time_wait}) che la
-  presenza dello stato \texttt{TIME\_WAIT} ha una ragione, ed infatti se si
-  usa questa opzione esiste sempre una probabilità, anche se estremamente
-  remota,\footnote{perché ciò avvenga infatti non solo devono coincidere gli
-    indirizzi IP e le porte degli estremi della nuova connessione, ma anche i
-    numeri di sequenza dei pacchetti, e questo è estremamente improbabile.}
-  che eventuali pacchetti rimasti intrappolati in una precedente connessione
-  possano finire fra quelli di una nuova.
-
-  Il secondo caso in cui viene usata questa opzione è quando si ha una
-  macchina cui sono assegnati diversi numeri IP (o come suol dirsi
-  \textit{multi-homed}) e si vuole porre in ascolto sulla stessa porta un
-  programma diverso (o una istanza diversa dello stesso programma) per
-  indirizzi IP diversi. Si ricordi infatti che è sempre possibile indicare a
-  \func{bind} di collegarsi solo su di un indirizzo specifico; in tal caso se
-  un altro programma cerca di riutilizzare la stessa porta (anche specificando
-  un indirizzo diverso) otterrà un errore a meno di non aver preventivamente
-  impostato \const{SO\_REUSEADDR}. Usando questa opzione diventa anche
-  possibile eseguire \func{bind} sull'indirizzo generico, e questo permetterà
-  il collegamento per tutti gli indirizzi (di quelli presenti) per i quali la
-  porta non risulti occupata da una precedente chiamata più specifica. Infine
-  si tenga presente che con il protocollo TCP non è mai possibile far partire
-  server che eseguano \func{bind} sullo stesso indirizzo e la stessa porta,
-  cioè ottenere quello che viene chiamato un \textit{completely duplicate
-    binding}.
-
-  Il terzo impiego è simile al precedente e prevede l'uso di \func{bind}
-  all'interno dello stesso programma per associare indirizzi locali diversi a
-  socket diversi. In genere questo viene fatto per i socket UDP quando è
-  necessario ottenere l'indirizzo a cui sono rivolte le richieste del client
-  ed il sistema non supporta l'opzione \const{IP\_RECVDSTADDR};\footnote{nel
-    caso di Linux questa opzione è stata supportata per in certo periodo nello
-    sviluppo del kernel 2.1.x, ma è in seguito stata soppiantata dall'uso di
-    \const{IP\_PKTINFO} (vedi sez.~\ref{sec:sock_ipv4_options}).} in tale modo
-  si può sapere a quale socket corrisponde un certo indirizzo.  Non ha senso
-  per socket TCP dato che su di essi si può sempre invocare \func{getsockname}
-  una volta che si è completata la connessione.
-
-  Infine il quarto caso è quello in si vuole effettivamente ottenere un
-  \textit{completely duplicate binding} 
+  socket.  Maggiori dettagli sul suo funzionamento sono forniti in
+  sez.~\ref{sec:sock_options_main}.
 
 
 \item[\const{SO\_TYPE}] questa opzione permette di leggere il tipo di socket
@@ -2353,7 +2257,14 @@ allora il seguente:
   valori di \func{sysctl} (vedi sez.~\ref{sec:sock_sysctl}).
    
 
-\item[\const{SO\_LINGER}] 
+\item[\const{SO\_LINGER}] questa opzione controlla le modalità con cui viene
+  chiuso un socket quando si utilizza un protocollo che supporta le
+  connessioni (è pertanto usata con i socket TCP ed ignorata per UDP) e
+  modifica il comportamento delle funzioni \func{close} e \func{shutdown}.
+  L'opzione richiede che l'argomento \param{optval} sia una struttura di tipo
+  \struct{linger}, definita in \texttt{sys/socket.h} ed illustrata in
+  fig.~\ref{fig:sock_linger_struct}.  Maggiori dettagli sul suo funzionamento
+  sono forniti in sez.~\ref{sec:sock_options_main}.
 
 \item[\const{SO\_PRIORITY}] questa opzione permette di impostare le priorità
   per tutti i pacchetti che sono inviati sul socket, prende per \param{optval}
@@ -2374,6 +2285,214 @@ allora il seguente:
 \end{basedescript}
 
 
+\subsection{Le uso delle principali opzioni dei socket}
+\label{sec:sock_options_main}
+
+L'elenco sintetico delle caratteristiche delle opzioni dei socket riportato in
+sez.~\ref{sec:sock_generic_options} non è sufficientemente dettagliato per
+permetterci di approfondire il significato di alcune di esse, che assumono
+grande importanza nella programmazione dei socket. Per questo motivo
+tratteremo ulteriormente l'uso di alcune di esse in questa sezione.
+
+\index{\texttt{SO\_KEEPALIVE} (costante)|(}
+La prima opzione da approfondire è \const{SO\_KEEPALIVE}, che come accennato
+permette di controllare automaticamente lo stato di una connessione.  Una
+connessione infatti può restare attiva anche se non viene effettuato alcun
+traffico su di essa, ma in certi casi però può essere utile controllarne lo
+stato per accorgersi di eventuali problemi. 
+
+Per questo, se si imposta questa opzione, è cura del kernel inviare degli
+appositi messaggi sulla rete (detti appunto \textit{keep-alive}) per
+verificare se la connessione è attiva.  L'opzione funziona soltanto con socket
+che supportino le connessioni (non ha senso per socket UDP ad esempio), ed
+utilizza per \param{optval} un intero usato come valore logico.
+
+L'opzione si applica principalmente ai socket TCP.  Con le impostazioni di
+default (che sono riprese da BSD) Linux emette un messaggio di
+\textit{keep-alive} verso l'altro capo della connessione se questa è rimasta
+senza traffico per più di due ore. Se è tutto a posto il messaggio viene
+ricevuto e verrà emesso un segmento ACK di risposta, alla cui ricezione
+ripartirà un'altro ciclo di attesa per altre due ore di inattività; tutto ciò
+viene effettuato dal kernel e le applicazioni non riceveranno nessun dato.
+
+In caso di problemi invece si possono avere i due casi già illustrati in
+sez.~\ref{sec:TCP_conn_crash} per il caso di terminazione prococe del server:
+il primo è quello in cui la macchina remota è caduta ed è stata riavviata, per
+cui dopo il riavvio la connessione non viene più riconosciuta,\footnote{si
+  ricordi che un normale riavvio non ha questo effetto, in quanto si passa per
+  la chiusura del processo, che chiude anche il socket inviando un segmento
+  FIN all'altro capo della connessione.} e si otterrà come risposta un RST. In
+tal caso il socket viene chiuso dopo aver impostato un errore
+\errcode{ECONNRESET}.
+
+Se invece non viene ricevuta nessuna risposta (indice che la macchina non è
+più raggiungibile) l'emissione dei messaggi viene ripetuta ad intervalli di 75
+secondi ad un massimo di 9 volte\footnote{entrambi questi valori possono
+  essere opportunamente modificati con gli opportuni parametri illustrati in
+  sez.~\ref{sec:sock_sysctl}, si tenga presente che però questo vale a livello
+  di kernel ed i valori saranno applicati a \textsl{tutti} i socket.} (per un
+totale di 11 minuti e 15 secondi) dopo di che, se non si è ricevuta nessuna
+risposta, il socket viene chiuso dopo aver impostato un errore di
+\errcode{ETIMEDOUT}. Se invece si riceve in risposta ad uno di questi messaggi
+un pacchetto ICMP di destinazione irraggiungibile, verrà restituito l'errore
+corrispondente.
+
+In generale questa opzione serve per individuare una caduta della
+connessione,\footnote{il crash di un processo di nuovo comporta la chiusura di
+  tutti i file che aveva aperti e la relativa emissione degli opportuni
+  segmenti FIN nel caso dei socket.} e viene usata sui server per evitare di
+mantenere impegnate le risorse dedicate a trattare delle connessioni in realtà
+terminate.  Abilitandola le connessioni effettivamente terminate vengono
+chiuse ed una \func{select} potrà rilevare la conclusione delle stesse e
+ricevere il relativo errore. Si tenga però presente che non si ha la certezza
+assoluta che un errore di \errcode{ETIMEDOUT} corrisponda ad una reale
+conclusione della connessione, il problema potrebbe essere dovuto ad un
+problema di routing che perduri per un tempo maggiore di quello impiegato nei
+vari tentativi di ritrasmissione del \textit{keep-alive}.
+\index{\texttt{SO\_KEEPALIVE} (costante)|)}
+
+
+\index{\texttt{SO\_REUSEADDR} (costante)|(}
+La seconda opzione da approfondire è \const{SO\_REUSEADDR}.  Come Stevens
+sottolinea in \cite{UNP1} si distinguono quattro casi per l'utilizzo di questa
+opzione; il primo è quello in cui un server è terminato ma esistono ancora dei
+processi figli che mantengono attiva almeno una connessione remota che
+utilizza l'indirizzo locale. Quando si riavvia il server questo viene bloccato
+sulla chiamata a \func{bind} dato che la porta è ancora utilizzata in una
+connessione esistente.\footnote{questa è una delle domande più frequenti sui
+  newsgroup dedicati allo sviluppo, in quanto è piuttosto comune in questa
+  situazione quando si sta sviluppando un server che si ferma e si riavvia in
+  continuazione.}  Inoltre se si usa il protocollo TCP questo può avvenire
+anche dopo che l'ultimo processo figlio è terminato, dato che la connessione
+può restare attiva anche dopo la chiusura del socket mantenendosi nello stato
+\texttt{TIME\_WAIT}.
+
+Usando \const{SO\_REUSEADDR} fra la chiamata a \func{socket} e quella a
+\func{bind} si consente a quest'ultima di avere comunque successo anche se la
+connessione è attiva (o nello stato \texttt{TIME\_WAIT}). È bene però
+ricordare (si riveda quanto detto in sez.~\ref{sec:TCP_time_wait}) che la
+presenza dello stato \texttt{TIME\_WAIT} ha una ragione, ed infatti se si usa
+questa opzione esiste sempre una probabilità, anche se estremamente
+remota,\footnote{perché ciò avvenga infatti non solo devono coincidere gli
+  indirizzi IP e le porte degli estremi della nuova connessione, ma anche i
+  numeri di sequenza dei pacchetti, e questo è estremamente improbabile.}  che
+eventuali pacchetti rimasti intrappolati in una precedente connessione possano
+finire fra quelli di una nuova.
+
+Il secondo caso in cui viene usata questa opzione è quando si ha una macchina
+cui sono assegnati diversi numeri IP (o come suol dirsi \textit{multi-homed})
+e si vuole porre in ascolto sulla stessa porta un programma diverso (o una
+istanza diversa dello stesso programma) per indirizzi IP diversi. Si ricordi
+infatti che è sempre possibile indicare a \func{bind} di collegarsi solo su di
+un indirizzo specifico; in tal caso se un altro programma cerca di
+riutilizzare la stessa porta (anche specificando un indirizzo diverso) otterrà
+un errore a meno di non aver preventivamente impostato \const{SO\_REUSEADDR}.
+Usando questa opzione diventa anche possibile eseguire \func{bind}
+sull'indirizzo generico, e questo permetterà il collegamento per tutti gli
+indirizzi (di quelli presenti) per i quali la porta non risulti occupata da
+una precedente chiamata più specifica. Infine si tenga presente che con il
+protocollo TCP non è mai possibile far partire server che eseguano \func{bind}
+sullo stesso indirizzo e la stessa porta, cioè ottenere quello che viene
+chiamato un \textit{completely duplicate binding}.
+
+Il terzo impiego è simile al precedente e prevede l'uso di \func{bind}
+all'interno dello stesso programma per associare indirizzi locali diversi a
+socket diversi. In genere questo viene fatto per i socket UDP quando è
+necessario ottenere l'indirizzo a cui sono rivolte le richieste del client ed
+il sistema non supporta l'opzione \const{IP\_RECVDSTADDR};\footnote{nel caso
+  di Linux questa opzione è stata supportata per in certo periodo nello
+  sviluppo del kernel 2.1.x, ma è in seguito stata soppiantata dall'uso di
+  \const{IP\_PKTINFO} (vedi sez.~\ref{sec:sock_ipv4_options}).} in tale modo
+si può sapere a quale socket corrisponde un certo indirizzo.  Non ha senso per
+socket TCP dato che su di essi si può sempre invocare \func{getsockname} una
+volta che si è completata la connessione.
+
+Infine il quarto caso è quello in si vuole effettivamente ottenere un
+\textit{completely duplicate binding}, quando cioè si vuole eseguire
+\func{bind} su un indirizzo ed una porta che sono già \textsl{legati} ad un
+altro socket.  Questo ovviamente non ha senso per il normale traffico di rete,
+in cui i pacchetti vengono scambiati direttamente fra due applicazioni; ma
+quando un sistema supporta il traffico in multicast, in cui una applicazione
+invia i pacchetti a molte altre (vedi sez.~\ref{sec:multicast_xxx}), allora ha
+senso che su una macchina i pacchetti provenienti dal traffico in multicast
+possano essere ricevuti da più applicazioni\footnote{l'esempio classico di
+  traffico in multicast è quello di uno streaming di dati (audio, video,
+  ecc.), l'uso del multicast consente in tal caso di trasmettere un solo
+  pacchetto, che potrà essere ricevuto da tutti i possibili destinatari
+  (invece di inviarne un duplicato a ciascuno); in questo caso è perfettamente
+  logico aspettarsi che sulla stessa macchina più utenti possano lanciare un
+  programma che permetta loro di ricevere gli stessi dati.} o da diverse
+istanze della stessa applicazione.
+
+In questo caso utilizzando \const{SO\_REUSEADDR} si consente ad una
+applicazione eseguire \func{bind} sulla stessa porta ed indirizzo usata da
+un'altra, così che anche essa possa ricevere gli stessi pacchetti (chiaramente
+la cosa non ha alcun senso per i socket TCP, ed infatti in questo tipo di
+applicazione è normale l'uso del protovollo UDP). La regola è che quando si
+hanno più applicazioni che hanno eseguito \func{bind} sulla stessa porta, di
+tutti pacchetti destinati ad un indirizzo di broadcast o di multicast viene
+inviata una copia a ciascuna applicazione. Non è definito invece cosa accade
+qualora il pacchetto sia destinato ad un indirizzo normale (unicast).
+
+Essendo questo un caso particolare in alcuni sistemi (come BSD) è stata
+introdotta una opzione ulteriore, \const{SO\_REUSEPORT} che richiede che detta
+opzione sia specificata per tutti i socket per i quali si vuole eseguire il
+\textit{completely duplicate binding}. Nel caso di Linux questa opzione non
+esiste, ma il comportamento di \const{SO\_REUSEADDR} è analogo, sarà cioè
+possibile effettuare un \textit{completely duplicate binding} ed ottenere il
+successo di \func{bind} su un socket legato allo stesso indirizzo e porta solo
+se il primo programma che ha eseguito \func{bind} su di essi ha impostato
+questa opzione.\footnote{Questa restrizione permette di evitare il cosiddetto
+  \textit{port stealing}, in cui un programma, usando \const{SO\_REUSEADDR},
+  può collegarsi ad una porta già in uso e ricevere i pacchetti destinati ad
+  un altro programma; con questa caratteristica ciò è possibile soltanto se il
+  primo programma a consentirlo, avendo usato fin dall'inizio
+  \const{SO\_REUSEADDR}.}
+\index{\texttt{SO\_REUSEADDR} (costante)|)}
+
+
+\index{\texttt{SO\_LINGER} (costante)|(} La terza opzione da approfondire è
+\const{SO\_LINGER}; essa, come il nome suggerisce, consente di
+\textsl{indugiare} nella chiusura di un socket. Il comportamento standard sia
+di \func{close} che \func{shutdown} è quello di terminare immediatamente dopo
+la chiamata, mentre il procedimento di chiusura della connessione e l'invio
+sulla rete di tutti i dati ancora presenti nei buffer viene gestito in
+sottofondo dal kernel.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includestruct{listati/linger.h}
+  \end{minipage}
+  \caption{La struttura \structd{linger} richiesta come valore dell'argomento
+    \param{optval} per l'impostazione dell'opzione dei socket
+    \const{SO\_LINGER}.}
+  \label{fig:sock_linger_struct}
+\end{figure}
+
+L'uso di \const{SO\_LINGER} permette di modificare (ed eventualmente
+ripristinare) questo comportamento in base ai valori passati nei campi della
+stuttura \struct{linger}.  Fintanto che il valore del campo \var{l\_onoff} di
+\struct{linger} è nullo la modalità che viene impostata (qualunque sia il
+valore di \var{l\_linger}) è quella standard appena illustrata.
+
+Se però si utilizza un valore di \var{l\_onoff} diverso da zero per
+l'impostazione di \const{SO\_LINGER} il comportamento dipende dal valore di
+\var{l\_linger}; se quest'ultimo è nullo l'uso delle funzioni \func{close} e
+\func{shutdown} provoca la terminazione immediata della connessione: nel caso
+di TCP cioè non viene eseguito il procedimento di chiusura illustrato in
+sez.~\ref{sec:TCP_conn_term}, ma viene inviato un segmento di RST che termina
+immediatamente la connessione. Se invece \var{l\_linger} ha un valore diverso
+da zero sia \func{close} che \func{shutdown} si bloccano e non ritornano
+fintanto che non si sia concluso il procedimento di chiusura della
+connessione, o non siano passati il numero di secondi specificati da
+\var{l\_linger}.
+\index{\texttt{SO\_LINGER} (costante)|)}
+
+
+
+
+
 \subsection{Le opzioni per il protocollo IPv4}
 \label{sec:sock_ipv4_options}
 
@@ -2396,41 +2515,45 @@ opzioni in tab.~\ref{tab:sock_opt_iplevel}.
     \hline
     \hline
     \const{IP\_OPTIONS}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-                          .\\
+                          Imposta o riceve le opzioni di IP.\\
     \const{IP\_PKTINFO}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-                          .\\
+                          Passa un messaggio di informazione.\\
     \const{IP\_RECVTOS}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-                          .\\
+                          Passa un messaggio col campo TOS.\\
     \const{IP\_RECVTTL}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-                          .\\
+                          Passa un messaggio col campo TTL.\\
     \const{IP\_RECVOPTS}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-                          .\\
+                          Passa un messaggio con le opzioni IP.\\
     \const{IP\_RETOPTS}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-                          .\\
+                          Passa un messaggio con le opzioni IP non
+                          trattate.\\
     \const{IP\_TOS}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-                          .\\
+                          Imposta il valore del campo TOS.\\
     \const{IP\_TTL}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-                          .\\
+                          Imposta il valore del campo TTL.\\
     \const{IP\_HDRINCL}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-                          .\\
+                          Passa l'intestazione di IP nei dati.\\
     \const{IP\_RECVERR}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-                          .\\
+                          Abilita la gestione degli errori.\\
     \const{IP\_MTU\_DISCOVER}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-                          .\\
+                          Imposta il Path MTU Discovery.\\
     \const{IP\_MTU}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-                          .\\
+                          Legge il valore attuale della MTU.\\
     \const{IP\_ROUTER\_ALERT}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-                          .\\
+                          Imposta l'opzione \textit{IP router alert} sui
+                          pacchetti.\\
     \const{IP\_MULTICAST\_TTL}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-                          .\\
+                          Imposta il TTL per i pacchetti multicast.\\
     \const{IP\_MULTICAST\_LOOP}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-                          .\\
-    \const{IP\_ADD\_MEMBERSHIP}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-                          .\\
-    \const{IP\_DROP\_MEMBERSHIP}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-                          .\\
+                          Controlla il reinvio a se
+                          stessi dei dati di multicast.\\ 
+    \const{IP\_ADD\_MEMBERSHIP}&         &$\bullet$&$\bullet$&\texttt{int}& 
+                          Si unisce a un gruppo di multicast.\\
+    \const{IP\_DROP\_MEMBERSHIP}&        &$\bullet$&$\bullet$&\texttt{int}& 
+                          Si sgancia da un gruppo di multicast.\\
     \const{IP\_MULTICAST\_IF}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-                          .\\
+                          Imposta l'interfaccia locale di un socket
+                          multicast.\\ 
    \hline
   \end{tabular}
   \caption{Le opzioni disponibili al livello \const{SOL\_IP}.} 
@@ -2438,6 +2561,24 @@ opzioni in tab.~\ref{tab:sock_opt_iplevel}.
 \end{table}
 
 
+Le descrizioni di tab.~\ref{tab:sock_opt_iplevel} sono estremamente succinte,
+una maggiore quantità di dettagli su queste opzioni è fornito nel seguente
+elenco:
+\begin{basedescript}{\desclabelwidth{2.5cm}\desclabelstyle{\nextlinelabel}}
+\item[\const{IP\_MULTICAST\_LOOP}] L'opzione consente di decidere se i dati
+  che si inviano su un socket usato con il multicast vengano ricevuti anche
+  sulla stessa macchina da cui li si stanno inviando.  Prende per
+  \param{optval} un intero usato come valore logico. 
+
+  In generale se si vuole che eventuali client possano ricevere i dati che si
+  inviano occorre che questa funzionalità sia abilitata (come avviene di
+  default). Qualora però non si voglia generare traffico per dati che già sono
+  disponibili l'uso di questa opzione permette di disabilitare questo tipo di
+  traffico. 
+
+\end{basedescript}
+
+
 
 
 
index 90dbaf7a659424e75fac2c0332653fc63b9db3d1..03fb502bbaa8817ace2e0bee04347867a6f97de3 100644 (file)
@@ -461,17 +461,17 @@ dall'\href{http://www.ietf.org/rfc/rfc1700.txt}{RFC~1700} che contiene
 l'elenco delle porte assegnate dalla IANA (la \textit{Internet Assigned Number
   Authority}) ma l'elenco viene costantemente aggiornato e pubblicato su
 internet (una versione aggiornata si può trovare all'indirizzo
-\texttt{ftp://ftp.isi.edu/in-notes/iana/assignements/port-numbers}); inoltre
+\href{ftp://ftp.isi.edu/in-notes/iana/assignements/port-number}
+{\texttt{ftp://ftp.isi.edu/in-notes/iana/assignements/port-numbers}}); inoltre
 in un sistema unix-like un analogo elenco viene mantenuto nel file
 \file{/etc/services}, con la corrispondenza fra i vari numeri di porta ed il
 nome simbolico del servizio.  I numeri sono divisi in tre intervalli:
 
-\begin{enumerate}
-\item \textsl{le porte conosciute}. I numeri da 0 a 1023. Queste sono
-  controllate e assegnate dalla IANA. Se è possibile la stessa porta è
-  assegnata allo stesso servizio sia su UDP che su TCP (ad esempio la porta 22
-  è assegnata a SSH su entrambi i protocolli, anche se viene usata solo dal
-  TCP).
+\begin{enumerate*}
+\item \textsl{le porte note}. I numeri da 0 a 1023. Queste sono controllate e
+  assegnate dalla IANA. Se è possibile la stessa porta è assegnata allo stesso
+  servizio sia su UDP che su TCP (ad esempio la porta 22 è assegnata a SSH su
+  entrambi i protocolli, anche se viene usata solo dal TCP).
   
 \item \textsl{le porte registrate}. I numeri da 1024 a 49151. Queste porte non
   sono controllate dalla IANA, che però registra ed elenca chi usa queste
@@ -483,29 +483,36 @@ nome simbolico del servizio.  I numeri sono divisi in tre intervalli:
 \item \textsl{le porte private} o \textsl{dinamiche}. I numeri da 49152 a
   65535. La IANA non dice nulla riguardo a queste porte che pertanto
   sono i candidati naturali ad essere usate come porte effimere.
-\end{enumerate}
+\end{enumerate*}
 
 In realtà rispetto a quanto indicato
 nell'\href{http://www.ietf.org/rfc/rfc1700.txt}{RFC~1700} i vari sistemi hanno
 fatto scelte diverse per le porte effimere, in particolare in
-fig.~\ref{fig:TCP_port_alloc} sono riportate quelle di BSD e Linux.  Nel caso
-di Linux poi la scelta fra i due intervalli possibili viene fatta
-dinamicamente a seconda della memoria a disposizione del kernel per gestire le
-relative tabelle.
+fig.~\ref{fig:TCP_port_alloc} sono riportate quelle di BSD e Linux.
 
 \begin{figure}[!htb]
   \centering
-  \includegraphics[width=15cm]{img/port_alloc}  
+  \includegraphics[width=13cm]{img/port_alloc}  
   \caption{Allocazione dei numeri di porta.}
   \label{fig:TCP_port_alloc}
 \end{figure}
 
 I sistemi Unix hanno inoltre il concetto di \textsl{porte riservate} (che
 corrispondono alle porte con numero minore di 1024 e coincidono quindi con le
-porte conosciute). La loro caratteristica è che possono essere assegnate a un
-socket solo da un processo con i privilegi di amministratore, per far si che
-solo l'amministratore possa allocare queste porte per far partire i relativi
-servizi.
+\textsl{porte note}). La loro caratteristica è che possono essere assegnate a
+un socket solo da un processo con i privilegi di amministratore, per far sì
+che solo l'amministratore possa allocare queste porte per far partire i
+relativi servizi.
+
+Le \textsl{glibc} definiscono (in \texttt{netinet/in.h})
+\const{IPPORT\_RESERVED} e \const{IPPORT\_USERRESERVED}, in cui la prima (che
+vale 1024) indica il limite superiore delle porte riservate, e la seconda (che
+vale 5000) il limite inferiore delle porte a disposizione degli utenti.  La
+convenzione vorrebbe che le porte \textsl{effimere} siano allocate fra questi
+due valori. Nel caso di Linux questo è vero solo in uno dei due casi di
+fig.~\ref{fig:TCP_port_alloc}, e la scelta fra i due possibili intervalli
+viene fatta dinamicamente dal kernel a seconda della memoria disponibile per
+la gestione delle relative tabelle.
 
 Si tenga conto poi che ci sono alcuni client, in particolare \cmd{rsh} e
 \cmd{rlogin}, che richiedono una connessione su una porta riservata anche dal