tipi di socket. L'elenco dettagliato del significato di ciascuna di esse è
allora il seguente:
\begin{basedescript}{\desclabelwidth{3cm}\desclabelstyle{\nextlinelabel}}
-\item[\const{SO\_KEEPALIVE}] una connessione può restare attiva senza che non
- debba essere effettuato nessun traffico su di essa; in in certi casi 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.
+\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
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.
+ 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
+ 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}.
è 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.
+ 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
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}.
-
+ nei vari tentativi di ritrasmissione del \textit{keep-alive}.
\item[\const{SO\_OOBINLINE}] se questa opzione viene abilitata i dati
\textit{out-of-band} vengono inviati direttamente nel flusso di dati del
socket (e sono quindi letti con una normale \func{read}) invece che restare
disponibili solo per l'accesso con l'uso del flag \const{MSG\_OOB} di
- \func{recvmsg}. Tratteremo l'argomento in dettaglio in
+ \func{recvmsg}. L'argomento è trattato in dettaglio in
sez.~\ref{sec:TCP_urgent_data}. L'opzione funziona soltanto con socket che
supportino i dati \textit{out-of-band} (non ha senso per socket UDP ad
esempio), ed utilizza per \param{optval} un intero usato come valore logico.
-
\item[\const{SO\_RCVLOWAT}] questa opzione imposta il valore che indica il
numero minimo di byte che devono essere presenti nel buffer di ricezione
perché il kernel passi i dati all'utente, restituendoli ad una \func{read} o
sono dati in ingresso. L'opzione utilizza per \param{optval} un intero che
specifica il numero di byte, ma con Linux questo valore è sempre 1 e non può
essere cambiato; \func{getsockopt} leggerà questo valore mentre
- \func{setsockopt} darà un errore di \errcode{ENOPROTOOPT}.
+ \func{setsockopt} darà un errore di \errcode{ENOPROTOOPT}.
\item[\const{SO\_SNDLOWAT}] questa opzione imposta il valore che indica il
\func{write} di ritornare o segnalando ad una \func{select} (vedi
sez.~\ref{sec:TCP_sock_select}) che è possibile eseguire una scrittura.
L'opzione utilizza per \param{optval} un intero che specifica il numero di
- byte, ma con Linux questo valore è sempre 1 e non può essere cambiato;
- \func{getsockopt} leggerà questo valore mentre \func{setsockopt} darà un
- errore di \errcode{ENOPROTOOPT}.
+ byte, come per la precedente \const{SO\_RCVLOWAT} con Linux questo valore è
+ sempre 1 e non può essere cambiato; \func{getsockopt} leggerà questo valore
+ mentre \func{setsockopt} darà un errore di \errcode{ENOPROTOOPT}.
\item[\const{SO\_RCVTIMEO}] l'opzione permette di impostare un tempo massimo
identica a quella usata con \func{select}. Con \func{getsockopt} si può
leggere il valore attuale, mentre con \func{setsockopt} si imposta il tempo
voluto, usando un valore nullo per \struct{timeval} il timeout viene
- rimosso.
+ rimosso.
Se l'opzione viene attivata tutte le volte che una delle funzioni di lettura
(\func{read}, \func{readv}, \func{recv}, \func{recvfrom} e \func{recvmsg})
si blocca in attesa di dati per un tempo maggiore di quello impostato, essa
ritornerà un valore -1 e la variabile \var{errno} sarà impostata con un
errore di \errcode{EAGAIN} e \errcode{EWOULDBLOCK}, così come sarebbe
- avvenuto se si fosse aperto il socket in modalità non bloccante.
+ avvenuto se si fosse aperto il socket in modalità non bloccante.\footnote{in
+ teoria, se il numero di byte presenti nel buffer di ricezione fosse
+ inferiore a quello specificato da \const{SO\_RCVLOWAT}, l'effetto potrebbe
+ essere semplicemente quello di provocare l'uscita delle funzioni di
+ lettura restituendo il numero di byte fino ad allora ricevuti; dato che
+ con Linux questo valore è sempre 1 questo caso non esiste.}
+
+ In genere questa opzione non è molto utilizzata se si ha a che fare con la
+ lettura dei dati, in quanto è sempre possibile usare una \func{select} che
+ consente di specificare un \textit{timeout}; l'uso di \func{select} non
+ consente però di impostare il timout per l'uso di \func{connect}, per avere
+ il quale si può ricorrere a questa opzione.
+
+% verificare con un programma di test
\item[\const{SO\_SNDTIMEO}] l'opzione permette di impostare un tempo massimo
sulle operazioni di scrittura su un socket, ed usa gli stessi valori di
\const{SO\_RCVTIMEO}. In questo caso però si avrà un errore di
\errcode{EAGAIN} o \errcode{EWOULDBLOCK} per le funzioni di scrittura
\func{write}, \func{writev}, \func{send}, \func{sendfrom} e \func{sendmsg}
- qualora queste restino bloccate per un tempo maggiore di quello specificato.
+ qualora queste restino bloccate per un tempo maggiore di quello specificato.
\item[\const{SO\_BSDCOMPAT}] questa opzione abilita la compatibilità con il
comportamento di BSD (in particolare ne riproduce i bug). Attualmente è una
opzione usata solo per il protocollo UDP e ne è prevista la rimozione in
futuro. L'opzione utilizza per \param{optval} un intero usato come valore
- logico.
+ logico.
Quando viene abilitata gli errori riportati da messaggi ICMP per un socket
UDP non vengono passati al programma in user space. Con le versioni 2.0.x
del kernel erano anche abilitate altre opzioni per i socket raw, che sono
state rimosse con il passaggio al 2.2; è consigliato correggere i programmi
- piuttosto che usare questa funzione.
+ 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.
+ 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
unix-domain e può essere usata solo con \func{getsockopt}. Utilizza per
\param{optval} una apposita struttura \struct{ucred} (vedi
- sez.~\ref{sec:unix_socket_xxx}).
+ sez.~\ref{sec:unix_socket_xxx}).
\item[\const{SO\_BINDTODEVICE}] questa opzione permette di \textsl{legare} il
socket ad una particolare interfaccia interfaccia, in modo che esso possa
\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.
+ 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 è
effettiva solo per alcuni tipi di socket, ed in particolare per quelli della
famiglia \const{AF\_INET}; non è invece supportata per i \textit{packet
- socket} (vedi sez.~\ref{cha:advanced_socket_xxx}).
+ socket} (vedi sez.~\ref{cha:advanced_socket_xxx}).
\item[\const{SO\_DEBUG}] questa opzione abilita il debugging delle operazioni
comportamento è diverso da quanto avviene con BSD, dove l'opzione opera
solo sui socket TCP, causando la scrittura di tutti i pacchetti inviati
sulla rete su un buffer circolare che viene letto da un apposito
- programma, \cmd{trpt}.}
+ 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
controllo viene eseguito sulla porta.} è già in uso da parte di un altro
socket.
- Come Stevens sottolinea in \cite{APUE} si distinguono quattro casi per
+ 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.
+ 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.
+
+ Il punto più critico è che con il protocollo TCP questo può avvenire anche
+ dopo che l'ultimo processo figlio è terminato, in quanto 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
+ successo anche in questo caso. È bene però ricordare che (si riveda quanto
+ detto in sez.~\ref{sec:TCP_time_wait}) la presenza dello stato
+ \texttt{TIME\_WAIT} ha una ragione, e che 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.
+
\item[\const{SO\_TYPE}] questa opzione permette di leggere il tipo di socket
su cui si opera; funziona solo con \func{getsockopt}, ed utilizza per
\param{optval} un intero in cui verrà restituto il valore numerico che lo
- identifica (ad esempio \const{SOCK\_STREAM}).
+ identifica (ad esempio \const{SOCK\_STREAM}).
\item[\const{SO\_ACCEPTCONN}] questa opzione permette di rilevare se il socket
su cui opera è stato posto in modalità di ricezione di eventuali connessioni
con una chiamata a \func{listen}. L'opzione può essere usata soltanto con
\func{getsockopt} e utilizza per \param{optval} un intero in cui viene
- restituito 1 se il socket è in ascolto e 0 altrimenti.
+ restituito 1 se il socket è in ascolto e 0 altrimenti.
\item[\const{SO\_DONTROUTE}] questa opzione forza l'invio diretto dei
pacchetti del socket, saltando ogni processo relativo all'uso della tabella
attraverso le due funzioni \func{setsockopt} e \func{getsockopt}, alcune
funzionalità possono essere impostate attraverso quelle che sono le funzioni
classiche per il controllo delle proprietà dei file, cioè \func{fcntl} e
-\func{ioctl}.
+\func{ioctl}.
\subsection{L'uso di \func{fcntl} per i socket}
Abbiamo già trattato l'uso di \func{fcntl} in sez.~\ref{sec:file_fcntl}, dove
però ne abbiamo descritto le funzionalità nell'ambito della sua applicazione a
file descriptor associati a file normali; tratteremo qui invece il suo uso
-specifico quando la si impiega su file descriptor associati a dei socket.
+specifico quando la si impiega su file descriptor associati a dei socket.
\subsection{L'uso di \func{ioctl} per i socket}
Come per \func{fcntl} abbiamo trattato l'uso di \func{ioctl} in
sez.~\ref{sec:file_ioctl}, dove ne abbiamo descritto le funzionalità
nell'ambito dell'applicazione su file normali; tratteremo qui il suo uso
-specifico quando la si impiega su file descriptor associati a dei socket.
+specifico quando la si impiega su file descriptor associati a dei socket.
\subsection{L'uso di \func{sysctl} per le proprietà della rete}
impostazioni relative a proprietà generali dei socket (di tutti quelli di un
certo tipo o di tutti quelli che usano un certo protocollo) rispetto alle
funzioni viste finora che consentono di controllare quelle di un singolo
-socket.
+socket.