%% sockctrl.tex
%%
-%% Copyright (C) 2004-2017 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2004-2018 Simone Piccardi. Permission is granted to
%% copy, distribute and/or modify this document under the terms of the GNU Free
%% Documentation License, Version 1.1 or any later version published by the
%% Free Software Foundation; with the Invariant Sections being "Prefazione",
\label{sec:sock_resolver}
\itindbeg{resolver} La risoluzione dei nomi è associata tradizionalmente al
-servizio del \itindex{Domain~Name~Service} \textit{Domain Name Service} che
-permette di identificare le macchine su internet invece che per numero IP
+servizio del \itindex{Domain~Name~Service~(DNS)} \textit{Domain Name Service}
+che permette di identificare le macchine su internet invece che per numero IP
attraverso il relativo \textsl{nome a dominio}.\footnote{non staremo ad
entrare nei dettagli della definizione di cosa è un nome a dominio, dandolo
per noto, una introduzione alla problematica si trova in \cite{AGL} (cap.~9)
Per questo aspetto il file di configurazione principale del sistema è
\conffile{/etc/resolv.conf} che contiene in sostanza l'elenco degli indirizzi
-IP dei server DNS da contattare; a questo si affiancava (fino alle \acr{glibc}
+IP dei server DNS da contattare; a questo si affiancava (fino alla \acr{glibc}
2.4) il file \conffile{/etc/host.conf} il cui scopo principale era indicare
l'ordine in cui eseguire la risoluzione dei nomi (se usare prima i valori di
\conffile{/etc/hosts} o quelli del DNS). Tralasciamo i dettagli relativi alle
associate chiamato \textit{Name Service Switch}, cui abbiamo accennato anche in
sez.~\ref{sec:sys_user_group} per quanto riguarda la gestione dei dati
associati a utenti e gruppi. Il sistema è stato introdotto la prima volta
-nelle librerie standard di Solaris e le \acr{glibc} hanno ripreso lo stesso
+nella libreria standard di Solaris e la \acr{glibc} ha ripreso lo stesso
schema; si tenga presente che questo sistema non esiste per altre librerie
-standard come le \acr{libc5} o le \acr{uclib}.
+standard come la \acr{libc5} o la \acr{uClib}.
Il \textit{Name Service Switch} (cui spesso si fa riferimento con l'acronimo
NSS) è un sistema di librerie dinamiche che permette di definire in maniera
fornite dal sistema del \textit{Name Service Switch}, dal punto di vista di un
programma che deve effettuare la risoluzione di un nome a dominio, tutto
quello che conta sono le funzioni classiche che il \textit{resolver} mette a
-disposizione (è cura delle \acr{glibc} tenere conto della presenza del
+disposizione (è cura della \acr{glibc} tenere conto della presenza del
\textit{Name Service Switch}) e sono queste quelle che tratteremo nelle
sezioni successive.
}
\end{funcbox}}
-La funzione è l'analoga di \func{perror} e stampa sullo standard error un
+La funzione è l'analoga di \func{perror} e stampa sullo \textit{standard error} un
messaggio di errore corrispondente al valore corrente di \var{h\_errno}, a cui
viene anteposta la stringa \param{string} passata come argomento. La seconda
funzione è \funcd{hstrerror} ed il suo prototipo è:
\const{RES\_USE\_INET6} nel campo \texttt{\_res.options} e poi chiamare
\func{res\_init} (vedi sez.~\ref{sec:sock_resolver_functions}) per modificare
le opzioni del \textit{resolver}; dato che questo non è molto comodo è stata
-definita (è una estensione fornita dalle \acr{glibc}, disponibile anche in
+definita (è una estensione fornita dalla \acr{glibc}, disponibile anche in
altri sistemi unix-like) un'altra funzione, \funcd{gethostbyname2}, il cui
prototipo è:
indirizzi generiche, questo sia ancora di tipo \texttt{char **} e si possa
riutilizzare lo stesso puntatore usato per i nomi.
-Per ciascun indirizzo valido si provvederà (\texttt{\small 41}) ad una
+Per ciascun indirizzo valido si provvederà (\texttt{\small 41}) a una
conversione con la funzione \func{inet\_ntop} (vedi
sez.~\ref{sec:sock_addr_func}) passandole gli opportuni argomenti, questa
restituirà la stringa da stampare (\texttt{\small 42}) con il valore
contenuti in essa (e così via se vi sono altre sotto-strutture con altri
puntatori) e copiare anche i dati da questi referenziati.}
-Per ovviare a questi problemi nelle \acr{glibc} sono definite anche delle
+Per ovviare a questi problemi nella \acr{glibc} sono definite anche delle
versioni rientranti delle precedenti funzioni, al solito queste sono
caratterizzate dall'avere un suffisso \texttt{\_r}, pertanto avremo le due
funzioni \funcd{gethostbyname\_r} e \funcd{gethostbyname2\_r} i cui prototipi
appropriata struttura contenente il valore dell'indirizzo IP (o IPv6) che si
vuole risolvere. L'uso del tipo \texttt{char *} per questo argomento è
storico, il dato dovrà essere fornito in una struttura \struct{in\_addr} per
-un indirizzo IPv4 ed una struttura \struct{in6\_addr} per un indirizzo IPv6;
-si ricordi che, come illustrato in fig.~\ref{fig:sock_sa_ipv4_struct}, che
-mentre \struct{in\_addr} in realtà corrisponde ad un numero intero, da
-esprimere comunque in \textit{network order}, non altrettanto avviene per
-\struct{in6\_addr}, pertanto è sempre opportuno inizializzare questi indirizzi
-con \func{inet\_pton} (vedi
-sez.~\ref{sec:sock_conv_func_gen}). Nell'argomento \param{len} se ne dovrà poi
-specificare la dimensione (rispettivamente 4 o 16), infine l'argomento
+un indirizzo IPv4 ed una struttura \struct{in6\_addr} per un indirizzo IPv6.
+
+Si ricordi inoltre, come illustrato in fig.~\ref{fig:sock_sa_ipv4_struct}, che
+mentre \struct{in\_addr} corrisponde in realtà ad un oridinario numero intero
+a 32 bit (da esprimere comunque in \textit{network order}) non altrettanto
+avviene per \struct{in6\_addr}, pertanto è sempre opportuno inizializzare
+questi indirizzi con \func{inet\_pton} (vedi
+sez.~\ref{sec:sock_conv_func_gen}).
+
+Nell'argomento \param{len} se ne dovrà poi specificare la dimensione
+(rispettivamente 4 o 16), infine l'argomento
\param{type} deve indicare il tipo di indirizzo, e dovrà essere o
\const{AF\_INET} o \const{AF\_INET6}.
Dato che \func{gethostbyaddr} usa un buffer statico, anche di questa funzione
esiste una versione rientrante \funcd{gethostbyaddr\_r} fornita come
-estensione dalle \acr{glibc}, il cui prototipo è:
+estensione dalla \acr{glibc}, il cui prototipo è:
\begin{funcproto}{
\fhead{netdb.h}
\func{gethostbyname2\_r} e devono essere usati allo stesso modo.
Infine lo standard POSIX prevede la presenza della funzione
-\funcm{gethostent}, che dovrebbe ritornare la voce successiva nel database dei
-nomi a dominio, ma questo ha senso solo per la lettura dei dati da un file
-come \conffile{/etc/hosts} e non per i risultati del DNS. Nel caso della
-\acr{glibc} questa viene usata allora solo per la lettura di quest'ultimo,
-come avviene in altri sistemi, ed ignora le voci relative ad indirizzi
-IPv6. Dato che i risultati si possono ottenere in modo generico con le
-funzioni già illustrate, non la tratteremo esplicitamente, come non tratteremo
-la sua variante rientrante \funcm{gethostent\_r}.
-
-Per risolvere il problema dell'uso da parte delle due funzioni
-\func{gethostbyname} e \func{gethostbyaddr} di memoria statica che può essere
-sovrascritta fra due chiamate successive, e per avere sempre la possibilità di
-indicare esplicitamente il tipo di indirizzi voluto (cosa che non è possibile
-con \func{gethostbyname}), seguendo
-l'\href{http://www.ietf.org/rfc/rfc2553.txt}{RFC~2553} vennero introdotte due
-nuove funzioni di risoluzione,\footnote{le funzioni sono presenti nelle
- \acr{glibc} versione 2.1.96, ma essendo considerate deprecate (vedi
+\funcd{gethostent}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fdecl{struct hostent *gethostent(void)}
+\fdesc{Ottiene la voce successiva nel database dei nomi a dominio.}
+}
+
+{La funzione ritorna l'indirizzo ad una struttura \struct{hostent} in caso di
+ successo e \val{NULL} per un errore.}
+\end{funcproto}
+
+La funzione dovrebbe ritornare (come puntatore alla solita struttura
+\struct{hostent} allocata internamente) la voce successiva nel database dei
+nomi a dominio, ma questo ha un significato soltato quando è relativo alla
+lettura dei dati da un file come \conffile{/etc/hosts} e non per i risultati
+del DNS. Nel caso della \acr{glibc} questa viene usata allora solo per la
+lettura delle voci presenti in quest'ultimo, come avviene anche in altri
+sistemi unix-like, ed inoltre ignora le voci relative ad indirizzi IPv6.
+
+Della stessa funzione la \acr{glibc} fornisce anche una versione rientrante
+\funcd{gethostent\_r}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fdecl{struct hostent *gethostent\_r(struct hostent *ret, char *buf, size\_t buflen,\\
+\phantom{struct hostent *gethostent\_r(}struct hostent **result, int *h\_errnop);}
+\fdesc{Ottiene la voce successiva nel database dei nomi a dominio.}
+}
+
+{La funzione ritorna $0$ in caso di successo e un valore non nullo per un errore.}
+\end{funcproto}
+
+La funzione ha lo stesso effetto di \func{gethostent}; gli argomenti servono a
+restituire i risultati in maniera rientrante e vanno usati secondo le modalità
+già illustrate per \func{gethostbyname\_r} e \func{gethostbyname2\_r}.
+
+Dati i limiti delle funzioni \func{gethostbyname} e \func{gethostbyaddr} con
+l'uso di memoria statica che può essere sovrascritta fra due chiamate
+successive, e per avere sempre la possibilità di indicare esplicitamente il
+tipo di indirizzi voluto (cosa che non è possibile con \func{gethostbyname}),
+è stata successivamente proposta,
+nell'\href{http://www.ietf.org/rfc/rfc2553.txt}{RFC~2553} un diversa
+interfaccia con l'introduzione due nuove funzioni di
+risoluzione,\footnote{dette funzioni sono presenti nella \acr{glibc} 2.1.96,
+ ma essendo considerate deprecate (vedi
sez.~\ref{sec:sock_advanced_name_services}) sono state rimosse nelle
versioni successive.} \funcd{getipnodebyname} e \funcd{getipnodebyaddr}, i
cui prototipi sono:
una volta che questi non siano più necessari; a tale scopo viene fornita la
funzione \funcd{freehostent}, il cui prototipo è:
-
\begin{funcproto}{
\fhead{netdb.h}
\fhead{sys/types.h}
nomi dobbiamo citare le funzioni che permettono di interrogare gli altri
servizi di risoluzione dei nomi illustrati in sez.~\ref{sec:sock_resolver}; in
generale infatti ci sono una serie di funzioni nella forma
-\texttt{getXXXbyname} e \texttt{getXXXbyaddr} (dove \texttt{XXX} indica il
-servizio) per ciascuna delle informazioni di rete mantenute dal \textit{Name
- Service Switch} che permettono rispettivamente di trovare una corrispondenza
-cercando per nome o per numero.
+\texttt{get\textsl{XXX}byname} e \texttt{get\textsl{XXX}byaddr} (dove
+\texttt{\textsl{XXX}} indica il servizio) per ciascuna delle informazioni di
+rete mantenute dal \textit{Name Service Switch} che permettono rispettivamente
+di trovare una corrispondenza cercando per nome o per numero.
L'elenco di queste funzioni è riportato nelle colonne finali di
tab.~\ref{tab:name_resolution_functions}, dove le si sono suddivise rispetto
questo sono \funcd{getservbyname} e \funcd{getservbyport}, che permettono
rispettivamente di ottenere il numero di porta associato ad un servizio dato
il nome e viceversa; i loro prototipi sono:
-\begin{functions}
- \headdecl{netdb.h}
- \funcdecl{struct servent *getservbyname(const char *name, const char *proto)}
- \funcdecl{struct servent *getservbyport(int port, const char *proto)}
- Risolvono il nome di un servizio nel rispettivo numero di porta e viceversa.
-
- \bodydesc{Ritornano il puntatore ad una struttura \struct{servent} con i
- risultati in caso di successo, o \val{NULL} in caso di errore.}
-\end{functions}
+
+
+\begin{funcproto}{
+\fhead{netdb.h}
+\fdecl{struct servent *getservbyname(const char *name, const char *proto)}
+\fdecl{struct servent *getservbyport(int port, const char *proto)}
+\fdesc{Risolvono il nome di un servizio nel rispettivo numero di porta e viceversa.}
+}
+
+{Le funzioni ritornano il puntatore ad una struttura \struct{servent} con i
+ risultati in caso di successo e \val{NULL} per un errore.}
+\end{funcproto}
Entrambe le funzioni prendono come ultimo argomento una stringa \param{proto}
-che indica il protocollo per il quale si intende effettuare la
-ricerca,\footnote{le informazioni mantenute in \conffile{/etc/services}
- infatti sono relative sia alle porte usate su UDP che su TCP, occorre quindi
- specificare a quale dei due protocolli si fa riferimento.} che nel caso si
-IP può avere come valori possibili solo \texttt{udp} o
-\texttt{tcp};\footnote{in teoria si potrebbe avere un qualunque protocollo fra
- quelli citati in \conffile{/etc/protocols}, posto che lo stesso supporti il
- concetto di \textsl{porta}, in pratica questi due sono gli unici presenti.}
-se si specifica un puntatore nullo la ricerca sarà eseguita su un protocollo
+che indica il protocollo per il quale si intende effettuare la ricerca (le
+informazioni mantenute in \conffile{/etc/services} infatti sono relative sia
+alle porte usate su UDP che su TCP, occorre quindi specificare a quale dei due
+protocolli si fa riferimento) che nel caso di IP può avere come valori
+possibili solo \texttt{udp} o \texttt{tcp};\footnote{in teoria si potrebbe
+ avere un qualunque protocollo fra quelli citati in
+ \conffile{/etc/protocols}, posto che lo stesso supporti il concetto di
+ \textsl{porta}, in pratica questi due sono gli unici presenti.} se si
+specifica un puntatore nullo la ricerca sarà eseguita su un protocollo
qualsiasi.
Il primo argomento è il nome del servizio per \func{getservbyname},
utenti e dei gruppi. Nel caso specifico dei servizi avremo allora le tre
funzioni \funcd{setservent}, \funcd{getservent} e \funcd{endservent} i cui
prototipi sono:
-\begin{functions}
- \headdecl{netdb.h}
- \funcdecl{void setservent(int stayopen)}
- Apre il file \conffile{/etc/services} e si posiziona al suo inizio.
-
- \funcdecl{struct servent *getservent(void)}
- Legge la voce successiva nel file \conffile{/etc/services}.
- \funcdecl{void endservent(void)}
- Chiude il file \conffile{/etc/services}.
+\begin{funcproto}{
+\fhead{netdb.h}
+\fdecl{struct servent *getservent(void)}
+\fdesc{Legge la voce successiva nel file \conffile{/etc/services}.}
+\fdecl{void setservent(int stayopen)}
+\fdesc{Apre il file \conffile{/etc/services} e si posiziona al suo inizio.}
+\fdecl{void endservent(void)}
+\fdesc{Chiude il file \conffile{/etc/services}.}
+}
- \bodydesc{Le due funzioni \func{setservent} e \func{endservent} non
- restituiscono nulla, \func{getservent} restituisce il puntatore ad una
- struttura \struct{servent} in caso di successo e \val{NULL} in caso di
- errore o fine del file.}
-\end{functions}
+{Le due funzioni \func{setservent} e \func{endservent} non ritornano nulla,
+ \func{getservent} restituisce il puntatore ad una struttura \struct{servent}
+ in caso di successo e \val{NULL} per un errore o fine del file.}
+\end{funcproto}
La prima funzione, \func{getservent}, legge una singola voce a partire dalla
posizione corrente in \conffile{/etc/services}, pertanto si può eseguire una
voce. La seconda funzione, \func{setservent}, permette di aprire il file
\conffile{/etc/services} per una successiva lettura, ma se il file è già stato
aperto riporta la posizione di lettura alla prima voce del file, in questo
-modo si può far ricominciare da capo una lettura sequenziale. L'argomento
-\param{stayopen}, se diverso da zero, fa sì che il file resti aperto anche fra
-diverse chiamate a \func{getservbyname} e \func{getservbyport}.\footnote{di
- default dopo una chiamata a queste funzioni il file viene chiuso, cosicché
- una successiva chiamata a \func{getservent} riparte dall'inizio.} La terza
-funzione, \func{endservent}, provvede semplicemente a chiudere il file.
-
-Queste tre funzioni per la lettura sequenziale di nuovo sono presenti per
-ciascuno dei vari tipi di informazione relative alle reti di
-tab.~\ref{tab:name_resolution_functions}; questo significa che esistono
-altrettante funzioni nella forma \texttt{setXXXent}, \texttt{getXXXent} e
-\texttt{endXXXent}, analoghe alle precedenti per la risoluzione dei servizi,
-che abbiamo riportato in tab.~\ref{tab:name_sequential_read}. Essendo, a
-parte il tipo di informazione che viene trattato, sostanzialmente identiche
-nel funzionamento e di scarso utilizzo, non staremo a trattarle una per una,
-rimandando alle rispettive pagine di manuale.
+modo si può far ricominciare da capo una lettura sequenziale.
\begin{table}[!htb]
\centering
\label{tab:name_sequential_read}
\end{table}
+L'argomento \param{stayopen} di \func{setservent}, se diverso da zero, fa sì
+che il file resti aperto anche fra diverse chiamate a \func{getservbyname} e
+\func{getservbyport}; di default dopo una chiamata a queste funzioni il file
+viene chiuso, cosicché una successiva chiamata a \func{getservent} riparte
+dall'inizio. La terza funzione, \func{endservent}, provvede semplicemente a
+chiudere il file.
+
+Queste tre funzioni per la lettura sequenziale di nuovo sono presenti per
+ciascuno dei vari tipi di informazione relative alle reti di
+tab.~\ref{tab:name_resolution_functions}; questo significa che esistono
+altrettante funzioni nella forma \texttt{setXXXent}, \texttt{getXXXent} e
+\texttt{endXXXent}, analoghe alle precedenti per la risoluzione dei servizi,
+che abbiamo riportato in tab.~\ref{tab:name_sequential_read}. Essendo, a
+parte il tipo di informazione che viene trattato, sostanzialmente identiche
+nel funzionamento e di scarso utilizzo, non staremo a trattarle una per una,
+rimandando alle rispettive pagine di manuale.
+
\subsection{Le funzioni avanzate per la risoluzione dei nomi}
\label{sec:sock_advanced_name_services}
di vari inconvenienti come il fatto che usano informazioni statiche, e non
prevedono la possibilità di avere diverse classi di indirizzi. Anche se sono
state create delle estensioni o metodi diversi che permettono di risolvere
-alcuni di questi inconvenienti,\footnote{rimane ad esempio il problema
- generico che si deve sapere in anticipo quale tipo di indirizzi IP (IPv4 o
- IPv6) corrispondono ad un certo nome a dominio.} comunque esse non
-forniscono una interfaccia sufficientemente generica.
+alcuni di questi inconvenienti, comunque esse non forniscono una interfaccia
+sufficientemente generica.\footnote{rimane ad esempio il problema generico che
+ si deve sapere in anticipo quale tipo di indirizzi IP (IPv4 o IPv6)
+ corrispondono ad un certo nome a dominio.}
Inoltre in genere quando si ha a che fare con i socket non esiste soltanto il
problema della risoluzione del nome che identifica la macchina, ma anche
\var{getipnodebyaddr} ed è stata introdotta una interfaccia completamente
nuova.
-La prima funzione di questa interfaccia è \funcd{getaddrinfo},\footnote{la
- funzione è definita, insieme a \func{getnameinfo} che vedremo più avanti,
- nell'\href{http://www.ietf.org/rfc/rfc2553.txt}{RFC~2553}.} che combina le
+La prima funzione di questa interfaccia è \funcd{getaddrinfo}, che combina le
funzionalità delle precedenti \func{getipnodebyname}, \func{getipnodebyaddr},
\func{getservbyname} e \func{getservbyport}, consentendo di ottenere
contemporaneamente sia la risoluzione di un indirizzo simbolico che del nome
-di un servizio; il suo prototipo è:
-\begin{functions}
- \headdecl{netdb.h}
- \headdecl{sys/socket.h}
- \headdecl{netdb.h}
+di un servizio; la funzione è stata introdotta, insieme a \func{getnameinfo}
+che vedremo più avanti,
+nell'\href{http://www.ietf.org/rfc/rfc2553.txt}{RFC~2553} ed il suo prototipo è:
- \funcdecl{int getaddrinfo(const char *node, const char *service, const
- struct addrinfo *hints, struct addrinfo **res)}
- Esegue una risoluzione di un nome a dominio e di un nome di servizio.
+\begin{funcproto}{
+\fhead{netdb.h}
+\fhead{sys/socket.h}
+\fdecl{int getaddrinfo(const char *node, const char *service, const
+ struct addrinfo *hints, \\
+\phantom{int getaddrinfo(}struct addrinfo **res)}
+\fdesc{Esegue una risoluzione di un nome a dominio e di un nome di servizio.}
+}
- \bodydesc{La funzione restituisce 0 in caso di successo o un codice di
- errore diverso da zero in caso di fallimento.}
-\end{functions}
+{La funzione ritorna $0$ in caso di successo e un codice di errore diverso da
+ zero per un errore.}
+\end{funcproto}
La funzione prende come primo argomento il nome della macchina che si vuole
risolvere, specificato tramite la stringa \param{node}. Questo argomento,
\begin{figure}[!htb]
\footnotesize \centering
- \begin{minipage}[c]{0.80\textwidth}
+ \begin{minipage}[c]{0.90\textwidth}
\includestruct{listati/addrinfo.h}
\end{minipage}
\caption{La struttura \structd{addrinfo} usata nella nuova interfaccia POSIX
in fig.~\ref{fig:sock_addrinfo_struct}, viene usata sia in ingresso, per
passare dei valori di controllo alla funzione, che in uscita, per ricevere i
risultati. La definizione è ripresa direttamente dal file \headfiled{netdb.h}
-in questa struttura viene dichiarata, la pagina di manuale riporta
+in cui questa struttura viene dichiarata, la pagina di manuale riporta
\type{size\_t} come tipo di dato per il campo \var{ai\_addrlen}, qui viene
usata quanto previsto dallo standard POSIX, in cui viene utilizzato
\type{socklen\_t}; i due tipi di dati sono comunque equivalenti.
puntata da \param{hints}), mentre in uscita indicano il tipo di risultato
contenuto nella struttura.
-Tutti i campi seguenti vengono usati soltanto in uscita; il campo
-\var{ai\_addrlen} indica la dimensione della struttura degli indirizzi
-ottenuta come risultato, il cui contenuto sarà memorizzato nella struttura
-\struct{sockaddr} posta all'indirizzo puntato dal campo \var{ai\_addr}. Il
-campo \var{ai\_canonname} è un puntatore alla stringa contenente il nome
-canonico della macchina, ed infine, quando la funzione restituisce più di un
-risultato, \var{ai\_next} è un puntatore alla successiva struttura
-\struct{addrinfo} della lista.
+Tutti i campi seguenti vengono usati soltanto in uscita e devono essere nulli
+o \val{NULL} in ingresso; il campo \var{ai\_addrlen} indica la dimensione
+della struttura degli indirizzi ottenuta come risultato, il cui contenuto sarà
+memorizzato nella struttura \struct{sockaddr} posta all'indirizzo puntato dal
+campo \var{ai\_addr}. Il campo \var{ai\_canonname} è un puntatore alla stringa
+contenente il nome canonico della macchina, ed infine, quando la funzione
+restituisce più di un risultato, \var{ai\_next} è un puntatore alla successiva
+struttura \struct{addrinfo} della lista.
Ovviamente non è necessario dare dei suggerimenti in ingresso, ed usando
\val{NULL} come valore per l'argomento \param{hints} si possono compiere
I due campi \var{ai\_family} e \var{ai\_socktype} prendono gli stessi valori
degli analoghi argomenti della funzione \func{socket}; in particolare per
\var{ai\_family} si possono usare i valori di tab.~\ref{tab:net_pf_names} ma
-sono presi in considerazione solo \const{PF\_INET} e \const{PF\_INET6}, mentre
+sono presi in considerazione solo \const{AF\_INET} e \const{AF\_INET6}, mentre
se non si vuole specificare nessuna famiglia di indirizzi si può usare il
-valore \const{PF\_UNSPEC}. Allo stesso modo per \var{ai\_socktype} si possono
+valore \const{AF\_UNSPEC}. Allo stesso modo per \var{ai\_socktype} si possono
usare i valori illustrati in sez.~\ref{sec:sock_type} per indicare per quale
tipo di socket si vuole risolvere il servizio indicato, anche se i soli
significativi sono \const{SOCK\_STREAM} e \const{SOCK\_DGRAM}; in questo caso,
\begin{table}[!htb]
\centering
\footnotesize
- \begin{tabular}[c]{|l|p{10cm}|}
+ \begin{tabular}[c]{|l|p{8cm}|}
\hline
\textbf{Costante} & \textbf{Significato} \\
\hline
\hline
- \constd{AI\_PASSIVE} & Viene utilizzato per ottenere un indirizzo in
- formato adatto per una successiva chiamata a
- \func{bind}. Se specificato quando si è usato
- \val{NULL} come valore per \param{node} gli
- indirizzi restituiti saranno inizializzati al
- valore generico (\const{INADDR\_ANY} per IPv4 e
- \const{IN6ADDR\_ANY\_INIT} per IPv6), altrimenti
- verrà usato l'indirizzo dell'interfaccia di
- \textit{loopback}. Se invece non è impostato gli
- indirizzi verranno restituiti in formato adatto ad
- una chiamata a \func{connect} o \func{sendto}.\\
+ \const{AI\_ADDRCONFIG} & Stesso significato dell'analoga di
+ tab.~\ref{tab:sock_getipnodebyname_flags}.\\
+ \const{AI\_ALL} & Stesso significato dell'analoga di
+ tab.~\ref{tab:sock_getipnodebyname_flags}.\\
\constd{AI\_CANONNAME} & Richiede la restituzione del nome canonico della
macchina, che verrà salvato in una stringa il cui
indirizzo sarà restituito nel campo
tab.~\ref{tab:addrinfo_error_code}), in questo
modo si evita ogni chiamata alle funzioni di
risoluzione.\\
+ \constd{AI\_NUMERICSERVICE}& Analogo di \const{AI\_NUMERICHOST} per la
+ risoluzione di un servizio, con
+ \param{service} che deve essere espresso in forma
+ numerica.\\
+ \constd{AI\_PASSIVE} & Viene utilizzato per ottenere un indirizzo in
+ formato adatto per una successiva chiamata a
+ \func{bind}. Se specificato quando si è usato
+ \val{NULL} come valore per \param{node} gli
+ indirizzi restituiti saranno inizializzati al
+ valore generico (\const{INADDR\_ANY} per IPv4 e
+ \const{IN6ADDR\_ANY\_INIT} per IPv6), altrimenti
+ verrà usato l'indirizzo dell'interfaccia di
+ \textit{loopback}. Se invece non è impostato gli
+ indirizzi verranno restituiti in formato adatto ad
+ una chiamata a \func{connect} o \func{sendto}.\\
\const{AI\_V4MAPPED} & Stesso significato dell'analoga di
- tab.~\ref{tab:sock_getipnodebyname_flags}.\\
- \const{AI\_ALL} & Stesso significato dell'analoga di
- tab.~\ref{tab:sock_getipnodebyname_flags}.\\
- \const{AI\_ADDRCONFIG} & Stesso significato dell'analoga di
- tab.~\ref{tab:sock_getipnodebyname_flags}.\\
+ tab.~\ref{tab:sock_getipnodebyname_flags}.\\
+ \hline
+ \const{AI\_CANONIDN} & Se il nome canonico richiesto con
+ \const{AI\_CANONNAME} è codificato con questo
+ flag la codifica viene convertita in forma
+ leggibile nella localizzazione corrente.\\
+ \const{AI\_IDN} & Se specificato il nome viene convertito, se
+ necessario, nella codifica IDN, usando la
+ localizzazione corrente.\\
+ \const{AI\_IDN\_ALLOW\_UNASSIGNED} & attiva il controllo
+ \texttt{IDNA\_ALLOW\_UNASSIGNED}.\\
+ \const{AI\_AI\_IDN\_USE\_STD3\_ASCII\_RULES} & attiva il controllo
+ \texttt{IDNA\_USE\_STD3\_ASCII\_RULES}\\
\hline
\end{tabular}
\caption{Costanti associate ai bit del campo \var{ai\_flags} della struttura
\label{tab:ai_flags_values}
\end{table}
-
-Infine l'ultimo campo è \var{ai\_flags}; che deve essere impostato come una
-maschera binaria; i bit di questa variabile infatti vengono usati per dare
-delle indicazioni sul tipo di risoluzione voluta, ed hanno valori analoghi a
-quelli visti in sez.~\ref{sec:sock_name_services} per \func{getipnodebyname};
-il valore di \var{ai\_flags} può essere impostata con un OR aritmetico delle
-costanti di tab.~\ref{tab:ai_flags_values}, ciascuna delle quali identifica un
-bit della maschera.
+% TODO mettere riferimento a IDNA_ALLOW_UNASSIGNED e IDNA_USE_STD3_ASCII_RULES
+
+Infine gli ultimi dettagli si controllano con il campo \var{ai\_flags}; che
+deve essere impostato come una maschera binaria; i bit di questa variabile
+infatti vengono usati per dare delle indicazioni sul tipo di risoluzione
+voluta, ed hanno valori analoghi a quelli visti in
+sez.~\ref{sec:sock_name_services} per \func{getipnodebyname}; il valore di
+\var{ai\_flags} può essere impostata con un OR aritmetico delle costanti di
+tab.~\ref{tab:ai_flags_values}, ciascuna delle quali identifica un bit della
+maschera.
+
+Nella seconda parte della tabella si sono riportati i valori delle costanti
+aggiunte a partire dalla \acr{glibc} 2.3.4 per gestire la
+internazionalizazione dei nomi a dominio (IDN o \textit{Internationalized
+ Domain Names}) secondo quanto specificato
+nell'\href{http://www.ietf.org/rfc/rfc3490.txt}{RFC~3490} (potendo cioè usare
+codifiche di caratteri che consentono l'espressione di nomi a dominio in
+qualunque lingua).
+
+Come accennato passando un valore \val{NULL} per l'argomento \param{hints} si
+effettua una risuluzione generica, equivalente ad aver impostato un valore
+nullo per \var{ai\_family} e \var{ai\_socktype}, un valore \const{AF\_UNSPEC}
+per \var{ai\_family} e il valore \code{(AI\_V4MAPPED|AI\_ADDRCONFIG)} per
+\var{ai\_flags}.
La funzione restituisce un valore nullo in caso di successo, o un codice in
caso di errore. I valori usati come codice di errore sono riportati in
\textbf{Costante} & \textbf{Significato} \\
\hline
\hline
+ \constd{EAI\_ADDRFAMILY}& La richiesta non ha nessun indirizzo di rete
+ per la famiglia di indirizzi specificata. \\
+ \constd{EAI\_AGAIN} & Il DNS ha restituito un errore di risoluzione
+ temporaneo, si può ritentare in seguito. \\
+ \constd{EAI\_BADFLAGS}& Il campo \var{ai\_flags} contiene dei valori non
+ validi per i flag o si è richiesto
+ \const{AI\_CANONNAME} con \param{name} nullo. \\
+ \constd{EAI\_FAIL} & Il DNS ha restituito un errore di risoluzione
+ permanente. \\
\constd{EAI\_FAMILY} & La famiglia di indirizzi richiesta non è
supportata. \\
- \constd{EAI\_SOCKTYPE}& Il tipo di socket richiesto non è supportato. \\
- \constd{EAI\_BADFLAGS}& Il campo \var{ai\_flags} contiene dei valori non
- validi. \\
+ \constd{EAI\_MEMORY} & È stato impossibile allocare la memoria necessaria
+ alle operazioni. \\
+ \constd{EAI\_NODATA} & La macchina specificata esiste, ma non ha nessun
+ indirizzo di rete definito. \\
\constd{EAI\_NONAME} & Il nome a dominio o il servizio non sono noti,
viene usato questo errore anche quando si specifica
il valore \val{NULL} per entrambi gli argomenti
\constd{EAI\_SERVICE} & Il servizio richiesto non è disponibile per il tipo
di socket richiesto, anche se può esistere per
altri tipi di socket. \\
- \constd{EAI\_ADDRFAMILY}& La rete richiesta non ha nessun indirizzo di rete
- per la famiglia di indirizzi specificata. \\
- \constd{EAI\_NODATA} & La macchina specificata esiste, ma non ha nessun
- indirizzo di rete definito. \\
- \constd{EAI\_MEMORY} & È stato impossibile allocare la memoria necessaria
- alle operazioni. \\
- \constd{EAI\_FAIL} & Il DNS ha restituito un errore di risoluzione
- permanente. \\
- \constd{EAI\_AGAIN} & Il DNS ha restituito un errore di risoluzione
- temporaneo, si può ritentare in seguito. \\
+ \constd{EAI\_SOCKTYPE}& Il tipo di socket richiesto non è supportato. \\
\constd{EAI\_SYSTEM} & C'è stato un errore di sistema, si può controllare
\var{errno} per i dettagli. \\
% \hline
\end{table}
Come per i codici di errore di \func{gethostbyname} anche in questo caso è
-fornita una apposita funzione, analoga di \func{strerror}, che consente di
-utilizzarli direttamente per stampare a video un messaggio esplicativo; la
-funzione è \funcd{gai\_strerror} ed il suo prototipo è:
-\begin{functions}
- \headdecl{netdb.h}
-
- \funcdecl{const char *gai\_strerror(int errcode)}
+fornita una apposita funzione, simile a \func{strerror}, che consente di
+utilizzare direttamente il codice restituito dalla funzione per stampare a
+video un messaggio esplicativo; la funzione è \funcd{gai\_strerror} ed il suo
+prototipo è:
- Fornisce il messaggio corrispondente ad un errore di \func{getaddrinfo}.
+\begin{funcproto}{
+\fhead{netdb.h}
+\fdecl{const char *gai\_strerror(int errcode)}
+\fdesc{Fornisce il messaggio corrispondente ad un errore di \func{getaddrinfo}.}
+}
- \bodydesc{La funzione restituisce il puntatore alla stringa contenente il
- messaggio di errore.}
-\end{functions}
+{La funzione ritorna il puntatore alla stringa contenente il messaggio di
+ errore.}
+\end{funcproto}
La funzione restituisce un puntatore alla stringa contenente il messaggio
corrispondente dal codice di errore \param{errcode} ottenuto come valore di
ritorno di \func{getaddrinfo}. La stringa è allocata staticamente, ma essendo
-costante, ed accessibile in sola lettura, questo non comporta nessun problema
-di rientranza della funzione.
+costante ed accessibile in sola lettura, la funzione è rientrante.
Dato che ad un certo nome a dominio possono corrispondere più indirizzi IP
(sia IPv4 che IPv6), e che un certo servizio può essere fornito su protocolli
e tipi di socket diversi, in generale, a meno di non aver eseguito una
selezione specifica attraverso l'uso di \param{hints}, si otterrà una diversa
-struttura \struct{addrinfo} per ciascuna possibilità. Ad esempio se si
-richiede la risoluzione del servizio \textit{echo} per l'indirizzo
-\texttt{www.truelite.it}, e si imposta \const{AI\_CANONNAME} per avere anche
-la risoluzione del nome canonico, si avrà come risposta della funzione la
-lista illustrata in fig.~\ref{fig:sock_addrinfo_list}.
+struttura \struct{addrinfo} per ciascuna possibilità.
+
+Ad esempio se si richiede la risoluzione del servizio \textit{echo} per
+l'indirizzo \texttt{www.truelite.it}, e si imposta \const{AI\_CANONNAME} per
+avere anche la risoluzione del nome canonico, si avrà come risposta della
+funzione la lista illustrata in fig.~\ref{fig:sock_addrinfo_list}.
\begin{figure}[!htb]
\centering
restringere le ricerche su protocolli, tipi di socket o famiglie di indirizzi,
è disponibile nel file \texttt{mygetaddr.c} dei sorgenti allegati alla guida.
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
\footnotesize \centering
\begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/mygetaddr.c}
che stabilisce a quale famiglia di indirizzi fa riferimento la struttura in
esame. Le possibilità sono due, un indirizzo IPv4 o IPv6, se nessuna delle due
si verifica si provvede (\texttt{\small 27--30}) a stampare un messaggio di
-errore ed uscire.\footnote{questa eventualità non dovrebbe mai verificarsi,
- almeno fintanto che la funzione \func{getaddrinfo} lavora correttamente.}
+errore ed uscire (questa eventualità non dovrebbe comunque mai verificarsi,
+almeno fintanto che la funzione \func{getaddrinfo} lavora correttamente).
Per ciascuno delle due possibili famiglie di indirizzi si estraggono le
informazioni che poi verranno stampate alla fine del ciclo (\texttt{\small
sono presenti direttamente i valori finali, per l'uso con \func{inet\_ntop}
occorre comunque passare un puntatore agli stessi (ed il costrutto
\code{\&addr6->sin6\_addr} è corretto in quanto l'operatore \texttt{->} ha
- on questo caso precedenza su \texttt{\&}).}
+ in questo caso precedenza su \texttt{\&}).}
Una volta estratte dalla struttura \struct{addrinfo} tutte le informazioni
relative alla risoluzione richiesta e stampati i relativi valori, l'ultimo
nulla garantisce che vengano forniti prima i dati relativi ai servizi di un
determinato protocollo o tipo di socket, se ne sono presenti di diversi. Se
allora utilizziamo il nostro programma potremo verificare il risultato:
-\begin{Verbatim}
-[piccardi@gont sources]$ ./mygetaddr -c gapil.truelite.it echo
+\begin{Console}
+[piccardi@gont sources]$ \textbf{./mygetaddr -c gapil.truelite.it echo}
Canonical name sources2.truelite.it
IPv4 address:
Indirizzo 62.48.34.25
Indirizzo 62.48.34.25
Protocollo 17
Porta 7
-\end{Verbatim}
+\end{Console}
%$
Una volta estratti i risultati dalla \textit{linked list} puntata
da \param{res} se questa non viene più utilizzata si dovrà avere cura di
disallocare opportunamente tutta la memoria, per questo viene fornita
l'apposita funzione \funcd{freeaddrinfo}, il cui prototipo è:
-\begin{functions}
- \headdecl{netdb.h}
- \funcdecl{void freeaddrinfo(struct addrinfo *res)}
- Libera la memoria allocata da una precedente chiamata a \func{getaddrinfo}.
+\begin{funcproto}{
+\fhead{netdb.h}
+\fdecl{void freeaddrinfo(struct addrinfo *res)}
+\fdesc{Libera la memoria allocata da una precedente chiamata a \func{getaddrinfo}.}
+}
- \bodydesc{La funzione non restituisce nessun codice di errore.}
-\end{functions}
+{La funzione non restituisce nessun codice di errore.}
+\end{funcproto}
La funzione prende come unico argomento il puntatore \param{res}, ottenuto da
una precedente chiamata a \func{getaddrinfo}, e scandisce la lista delle
strutture per liberare tutta la memoria allocata. Dato che la funzione non ha
valori di ritorno deve essere posta molta cura nel passare un valore valido
-per \param{res}.
+per \param{res} ed usare un indirizzo non valido o già liberato può avere
+conseguenze non prevedibili.
Si tenga presente infine che se si copiano i risultati da una delle strutture
\struct{addrinfo} restituite nella lista indicizzata da \param{res}, occorre
dati i rispettivi valori numerici. La funzione che sostituisce le varie
\func{gethostbyname}, \func{getipnodebyname} e \func{getservbyname} è
\funcd{getnameinfo}, ed il suo prototipo è:
-\begin{functions}
- \headdecl{sys/socket.h}
- \headdecl{netdb.h}
- \funcdecl{int getnameinfo(const struct sockaddr *sa, socklen\_t salen, char
- *host, size\_t hostlen, char *serv, size\_t servlen, int flags)}
-
- Risolve il contenuto di una struttura degli indirizzi in maniera
- indipendente dal protocollo.
+\begin{funcproto}{
+\fhead{netdb.h}
+\fhead{sys/socket.h}
+\fdecl{int getnameinfo(const struct sockaddr *sa, socklen\_t salen, \\
+\phantom{int getnameinfo(}char *host, size\_t hostlen, char *serv, size\_t
+servlen, int flags)}
+\fdesc{Effettua una risoluzione di un indirizzo di rete in maniera
+ indipendente dal protocollo.}
+}
- \bodydesc{La funzione restituisce 0 in caso di successo e un codice di
- errore diverso da zero altrimenti.}
-\end{functions}
+{La funzione ritorna $0$ in caso di successo e un codice di errore diverso da
+ zero per un errore.}
+\end{funcproto}
La principale caratteristica di \func{getnameinfo} è che la funzione è in
grado di eseguire una risoluzione inversa in maniera indipendente dal
I risultati della funzione saranno restituiti nelle due stringhe puntate da
\param{host} e \param{serv}, che dovranno essere state precedentemente
allocate per una lunghezza massima che deve essere specificata con gli altri
-due argomenti \param{hostlen} e \param{servlen}. Si può, quando non si è
-interessati ad uno dei due, passare il valore \val{NULL} come argomento,
-così che la corrispondente informazione non verrà richiesta. Infine l'ultimo
+due argomenti \param{hostlen} e \param{servlen}. Quando non si è
+interessati ad uno dei due, si può passare il valore \val{NULL} come argomento,
+così che la corrispondente informazione non venga richiesta. Infine l'ultimo
argomento \param{flags} è una maschera binaria i cui bit consentono di
impostare le modalità con cui viene eseguita la ricerca, e deve essere
specificato attraverso l'OR aritmetico dei valori illustrati in
-tab.~\ref{tab:getnameinfo_flags}.
+tab.~\ref{tab:getnameinfo_flags}, nella seconda parte della tabella si sono
+aggiunti i valori introdotto con la \acr{glibc} 2.3.4 per gestire la
+internazionalizzione dei nomi a dominio.
\begin{table}[!htb]
\centering
\footnotesize
- \begin{tabular}[c]{|l|p{10cm}|}
+ \begin{tabular}[c]{|l|p{8cm}|}
\hline
\textbf{Costante} & \textbf{Significato} \\
\hline
\hline
+ \constd{NI\_DGRAM} & Richiede che venga restituito il nome del
+ servizio su UDP invece che quello su TCP per quei
+ pichi servizi (porte 512-214) che soni diversi
+ nei due protocolli.\\
\constd{NI\_NOFQDN} & Richiede che venga restituita solo il nome della
macchina all'interno del dominio al posto del
nome completo (FQDN).\\
+ \constd{NI\_NAMEREQD} & Richiede la restituzione di un errore se il nome
+ non può essere risolto.\\
\constd{NI\_NUMERICHOST}& Richiede che venga restituita la forma numerica
dell'indirizzo (questo succede sempre se il nome
non può essere ottenuto).\\
- \constd{NI\_NAMEREQD} & Richiede la restituzione di un errore se il nome
- non può essere risolto.\\
\constd{NI\_NUMERICSERV}& Richiede che il servizio venga restituito in
- forma numerica (attraverso il numero di porta).\\
- \constd{NI\_DGRAM} & Richiede che venga restituito il nome del
- servizio su UDP invece che quello su TCP per quei
- pichi servizi (porte 512-214) che soni diversi
- nei due protocolli.\\
+ forma numerica (attraverso il numero di
+ porta).\\
+ \hline
+ \const{NI\_IDN} & Se specificato il nome restituito viene convertito usando la
+ localizzazione corrente, se necessario, nella
+ codifica IDN.\\
+ \const{NI\_IDN\_ALLOW\_UNASSIGNED} & attiva il controllo
+ \texttt{IDNA\_ALLOW\_UNASSIGNED}.\\
+ \const{NI\_AI\_IDN\_USE\_STD3\_ASCII\_RULES} & attiva il controllo
+ \texttt{IDNA\_USE\_STD3\_ASCII\_RULES}\\
\hline
\end{tabular}
\caption{Costanti associate ai bit dell'argomento \param{flags} della
dei sorgenti allegati alla guida, che contiene varie funzioni di utilità per
l'uso dei socket.
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
\footnotesize \centering
\begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/sockconn.c}
specificare con il valore numerico di \conffile{/etc/protocols}) ed il tipo di
socket (al solito specificato con i valori illustrati in
sez.~\ref{sec:sock_type}). La funzione ritorna il valore del file descriptor
-associato al socket (un numero positivo) in caso di successo, o -1 in caso di
-errore; per risolvere il problema di non poter passare indietro i valori di
-ritorno di \func{getaddrinfo} contenenti i relativi codici di
-errore\footnote{non si può avere nessuna certezza che detti valori siano
- negativi, è questo è invece necessario per evitare ogni possibile ambiguità
- nei confronti del valore di ritorno in caso di successo.} si sono stampati i
-messaggi d'errore direttamente nella funzione.
-
-Una volta definite le variabili necessarie (\texttt{\small 3--5}) la funzione
+associato al socket (un numero positivo) in caso di successo, o $-1$ in caso
+di errore.
+
+Per risolvere il problema di non poter passare indietro i valori di ritorno di
+\func{getaddrinfo} contenenti i relativi codici di errore si sono stampati i
+messaggi d'errore direttamente nella funzione; infatti non si può avere
+nessuna certezza che detti valori siano negativi e per cui stampare subito
+l'errore diventa necessario per evitare ogni possibile ambiguità nei confronti
+del valore di ritorno in caso di successo.
+
+Una volta definite le variabili occorrenti (\texttt{\small 3--5}) la funzione
prima (\texttt{\small 6}) azzera il contenuto della struttura \var{hint} e poi
provvede (\texttt{\small 7--9}) ad inizializzarne i valori necessari per la
chiamata (\texttt{\small 10}) a \func{getaddrinfo}. Di quest'ultima si
-controlla (\texttt{\small 12--16}) il codice di ritorno, in modo da stampare un
-avviso di errore, azzerare \var{errno} ed uscire in caso di errore. Dato che
-ad una macchina possono corrispondere più indirizzi IP, e di tipo diverso (sia
-IPv4 che IPv6), mentre il servizio può essere in ascolto soltanto su uno solo
-di questi, si provvede a tentare la connessione per ciascun indirizzo
-restituito all'interno di un ciclo (\texttt{\small 18--40}) di scansione della
-lista restituita da \func{getaddrinfo}, ma prima (\texttt{\small 17}) si salva
-il valore del puntatore per poterlo riutilizzare alla fine per disallocare la
-lista.
+controlla (\texttt{\small 12--16}) il codice di ritorno, in modo da stampare
+un avviso di errore, azzerare \var{errno} ed uscire in caso di errore.
+
+Dato che ad una macchina possono corrispondere più indirizzi IP, e di tipo
+diverso (sia IPv4 che IPv6), mentre il servizio può essere in ascolto soltanto
+su uno solo di questi, si provvede a tentare la connessione per ciascun
+indirizzo restituito all'interno di un ciclo (\texttt{\small 18--40}) di
+scansione della lista restituita da \func{getaddrinfo}, ma prima
+(\texttt{\small 17}) si salva il valore del puntatore per poterlo riutilizzare
+alla fine per disallocare la lista.
Il ciclo viene ripetuto (\texttt{\small 18}) fintanto che si hanno indirizzi
validi, ed inizia (\texttt{\small 19}) con l'apertura del socket; se questa
fallisce si controlla (\texttt{\small 20}) se sono disponibili altri
indirizzi, nel qual caso si passa al successivo (\texttt{\small 21}) e si
riprende (\texttt{\small 22}) il ciclo da capo; se non ve ne sono si stampa
-l'errore ritornando immediatamente (\texttt{\small 24--27}). Quando la
-creazione del socket ha avuto successo si procede (\texttt{\small 29})
-direttamente con la connessione, di nuovo in caso di fallimento viene ripetuto
-(\texttt{\small 30--38}) il controllo se vi sono o no altri indirizzi da
-provare nella stessa modalità fatta in precedenza, aggiungendovi però in
+l'errore ritornando immediatamente (\texttt{\small 24--27}).
+
+Quando la creazione del socket ha avuto successo si procede (\texttt{\small
+ 29}) direttamente con la connessione, di nuovo in caso di fallimento viene
+ripetuto (\texttt{\small 30--38}) il controllo se vi sono o no altri indirizzi
+da provare nella stessa modalità fatta in precedenza, aggiungendovi però in
entrambi i casi (\texttt{\small 32} e (\texttt{\small 36}) la chiusura del
socket precedentemente aperto, che non è più utilizzabile.
dati relativi alle strutture degli indirizzi di \struct{addrinfo} che sono
opachi rispetto all'uso della funzione \func{connect}.
-\begin{figure}[!htbp]
- \footnotesize \centering
- \begin{minipage}[c]{\codesamplewidth}
- \includecodesample{listati/TCP_echo_fifth.c}
- \end{minipage}
- \normalsize
- \caption{Il nuovo codice per la connessione del client \textit{echo}.}
- \label{fig:TCP_echo_fifth}
-\end{figure}
-
Per usare questa funzione possiamo allora modificare ulteriormente il nostro
programma client per il servizio \textit{echo}; in questo caso rispetto al
codice usato finora per collegarsi (vedi fig.~\ref{fig:TCP_echo_client_1})
consente di utilizzare come argomento del programma un nome a dominio al posto
dell'indirizzo numerico, e può utilizzare sia indirizzi IPv4 che IPv6.
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/TCP_echo_fifth.c}
+ \end{minipage}
+ \normalsize
+ \caption{Il nuovo codice per la connessione del client \textit{echo}.}
+ \label{fig:TCP_echo_fifth}
+\end{figure}
+
+La seconda funzione di ausilio che abbiamo creato è \texttt{sockbind}, il cui
+corpo principale è riportato in fig.~\ref{fig:sockbind_code} (al solito il
+sorgente completo è nel file \file{sockbind.c} dei sorgenti allegati alla
+guida). Come si può notare la funzione è del tutto analoga alla precedente
+\texttt{sockconn}, e prende gli stessi argomenti, però invece di eseguire una
+connessione con \func{connect} si limita a chiamare \func{bind} per collegare
+il socket ad una porta.
+
+\begin{figure}[!htb]
\footnotesize \centering
\begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/sockbind.c}
\label{fig:sockbind_code}
\end{figure}
-La seconda funzione di ausilio è \texttt{sockbind}, il cui corpo principale è
-riportato in fig.~\ref{fig:sockbind_code} (al solito il sorgente completo è
-nel file \file{sockbind.c} dei sorgenti allegati alla guida). Come si può
-notare la funzione è del tutto analoga alla precedente \texttt{sockconn}, e
-prende gli stessi argomenti, però invece di eseguire una connessione con
-\func{connect} si limita a chiamare \func{bind} per collegare il socket ad una
-porta.
-
Dato che la funzione è pensata per essere utilizzata da un server ci si può
chiedere a quale scopo mantenere l'argomento \param{host} quando l'indirizzo
di questo è usualmente noto. Si ricordi però quanto detto in
(\texttt{\small 43--44}) della funzione è identica.
Si noti come anche in questo caso si siano inserite le stampe degli errori
-sullo standard error, nonostante la funzione possa essere invocata da un
-demone. Nel nostro caso questo non è un problema in quanto se la funzione non
-ha successo il programma deve uscire immediatamente prima di essere posto in
-background, e può quindi scrivere gli errori direttamente sullo standard
-error.
+sullo \textit{standard error}, nonostante la funzione possa essere invocata da
+un demone. Nel nostro caso questo non è un problema in quanto se la funzione
+non ha successo il programma deve uscire immediatamente prima di essere posto
+in background, e può quindi scrivere gli errori direttamente sullo
+\textit{standard error}.
\begin{figure}[!htbp]
\footnotesize \centering
quale si voglia far ascoltare il server.
-
\section{Le opzioni dei socket}
\label{sec:sock_options}
Benché dal punto di vista del loro uso come canali di trasmissione di dati i
-socket siano trattati allo stesso modo dei file, ed acceduti tramite i file
-descriptor, la normale interfaccia usata per la gestione dei file non è
-sufficiente a poterne controllare tutte le caratteristiche, che variano tra
-l'altro a seconda del loro tipo (e della relativa forma di comunicazione
-sottostante). In questa sezione vedremo allora quali sono le funzioni dedicate
-alla gestione delle caratteristiche specifiche dei vari tipi di socket, le
-cosiddette \textit{socket options}.
-
-
-\subsection{Le funzioni \func{setsockopt} e \func{getsockopt}}
+socket vengano trattati allo stesso modo dei file, acceduti tramite i file
+descriptor, e gestiti con le ordinarie funzioni di lettura e scrittura dei
+file, l'interfaccia standard usata per la gestione dei file generici non è
+comunque sufficiente a controllare la moltitudine di caratteristiche
+specifiche che li contraddistinguono, considerato tra l'altro che queste
+possono essere completamente diverse fra loro a seconda del tipo di socket e
+della relativa forma di comunicazione sottostante.
+
+In questa sezione vedremo allora quali sono le funzioni dedicate alla gestione
+delle caratteristiche specifiche dei vari tipi di socket, che vengono
+raggruppate sotto il nome generico di ``\textit{socket options}'', ma
+soprattutto analizzaremo quali sono queste opzioni e quali caretteristiche e
+comportamenti dei socket permettono di controllare.
+
+
+\subsection{Le funzioni di gestione delle opzioni dei socket}
\label{sec:sock_setsockopt}
-Le varie caratteristiche dei socket possono essere gestite attraverso l'uso di
-due funzioni generiche che permettono rispettivamente di impostarle e di
-recuperarne il valore corrente. La prima di queste due funzioni, quella usata
-per impostare le \textit{socket options}, è \funcd{setsockopt}, ed il suo
-prototipo è:
-\begin{functions}
- \headdecl{sys/socket.h}
- \headdecl{sys/types.h}
+La modalità principale con cui si possono gestire le caratteristiche dei
+socket (ne vedremo delle ulteriori nelle prossime sezioni) è quella che passa
+attraverso l'uso di due funzioni di sistema generiche che permettono
+rispettivamente di impostarle e di recuperarne il valore corrente. La prima di
+queste due funzioni, quella usata per impostare le \textit{socket options}, è
+\funcd{setsockopt}, ed il suo prototipo è:
- \funcdecl{int setsockopt(int sock, int level, int optname, const void
+\begin{funcproto}{
+\fhead{sys/socket.h}
+\fhead{sys/types.h}
+\fdecl{int setsockopt(int sock, int level, int optname, const void
*optval, socklen\_t optlen)}
- Imposta le opzioni di un socket.
+\fdesc{Imposta le opzioni di un socket.}
+}
- \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
- errore, nel qual caso \var{errno} assumerà i valori:
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
\begin{errlist}
\item[\errcode{EBADF}] il file descriptor \param{sock} non è valido.
\item[\errcode{EFAULT}] l'indirizzo \param{optval} non è valido.
un socket.
\end{errlist}
}
-\end{functions}
-
+\end{funcproto}
Il primo argomento della funzione, \param{sock}, indica il socket su cui si
intende operare; per indicare l'opzione da impostare si devono usare i due
\const{SOL\_SOCKET} usato per le opzioni generiche che sono disponibili per
qualunque tipo di socket.
-I valori usati per \param{level}, corrispondenti ad un dato protocollo usato
-da un socket, sono quelli corrispondenti al valore numerico che identifica il
-suddetto protocollo in \conffile{/etc/protocols}; dato che la leggibilità di un
-programma non trarrebbe certo beneficio dall'uso diretto dei valori numerici,
-più comunemente si indica il protocollo tramite le apposite costanti
-\texttt{SOL\_*} riportate in tab.~\ref{tab:sock_option_levels}, dove si sono
-riassunti i valori che possono essere usati per l'argomento
-\param{level}.\footnote{la notazione in questo caso è, purtroppo, abbastanza
- confusa: infatti in Linux il valore si può impostare sia usando le costanti
- \texttt{SOL\_*}, che le analoghe \texttt{IPPROTO\_*} (citate anche da
- Stevens in \cite{UNP1}); entrambe hanno gli stessi valori che sono
- equivalenti ai numeri di protocollo di \conffile{/etc/protocols}, con una
- eccezione specifica, che è quella del protocollo ICMP, per la quale non
- esista una costante, il che è comprensibile dato che il suo valore, 1, è
- quello che viene assegnato a \const{SOL\_SOCKET}.}
-
\begin{table}[!htb]
\centering
\footnotesize
\label{tab:sock_option_levels}
\end{table}
+I valori usati per \param{level}, corrispondenti ad un dato protocollo usato
+da un socket, sono quelli corrispondenti al valore numerico che identifica il
+suddetto protocollo in \conffile{/etc/protocols}; dato che la leggibilità di un
+programma non trarrebbe certo beneficio dall'uso diretto dei valori numerici,
+più comunemente si indica il protocollo tramite le apposite costanti
+\texttt{SOL\_*} riportate in tab.~\ref{tab:sock_option_levels}, dove si sono
+riassunti i valori che possono essere usati per l'argomento
+\param{level}.
+
+La notazione in questo caso è, purtroppo, abbastanza confusa: infatti in Linux
+il valore si può impostare sia usando le costanti \texttt{SOL\_*}, che le
+analoghe \texttt{IPPROTO\_*} (citate anche da Stevens in \cite{UNP1});
+entrambe hanno gli stessi valori che sono equivalenti ai numeri di protocollo
+di \conffile{/etc/protocols}, con una eccezione specifica, che è quella del
+protocollo ICMP, per la quale non esiste una costante, il che è comprensibile
+dato che il suo valore, 1, è quello che viene assegnato a \const{SOL\_SOCKET}.
+
Il quarto argomento, \param{optval} è un puntatore ad una zona di memoria che
contiene i dati che specificano il valore dell'opzione che si vuole passare al
socket, mentre l'ultimo argomento \param{optlen},\footnote{questo argomento è
in realtà sempre di tipo \ctyp{int}, come era nelle \acr{libc4} e
\acr{libc5}; l'uso di \type{socklen\_t} è stato introdotto da POSIX (valgono
le stesse considerazioni per l'uso di questo tipo di dato fatte in
- sez.~\ref{sec:TCP_func_accept}) ed adottato dalle \acr{glibc}.} è la
+ sez.~\ref{sec:TCP_func_accept}) ed adottato dalla \acr{glibc}.} è la
dimensione in byte dei dati presenti all'indirizzo indicato da \param{optval}.
Dato che il tipo di dati varia a seconda dell'opzione scelta, occorrerà
individuare qual è quello che deve essere usato, ed utilizzare le opportune
La seconda funzione usata per controllare le proprietà dei socket è
\funcd{getsockopt}, che serve a leggere i valori delle opzioni dei socket ed a
farsi restituire i dati relativi al loro funzionamento; il suo prototipo è:
-\begin{functions}
- \headdecl{sys/socket.h}
- \headdecl{sys/types.h}
- \funcdecl{int getsockopt(int s, int level, int optname, void *optval,
- socklen\_t *optlen)} Legge le opzioni di un socket.
- \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
- errore, nel qual caso \var{errno} assumerà i valori:
+\begin{funcproto}{
+\fhead{sys/socket.h}
+\fhead{sys/types.h}
+\fdecl{int getsockopt(int s, int level, int optname, void *optval,
+ socklen\_t *optlen)}
+\fdesc{Legge le opzioni di un socket.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
\begin{errlist}
\item[\errcode{EBADF}] il file descriptor \param{sock} non è valido.
\item[\errcode{EFAULT}] l'indirizzo \param{optval} o quello di
un socket.
\end{errlist}
}
-\end{functions}
+\end{funcproto}
I primi tre argomenti sono identici ed hanno lo stesso significato di quelli
di \func{setsockopt}, anche se non è detto che tutte le opzioni siano definite
\label{sec:sock_generic_options}
Come accennato esiste un insieme generico di opzioni dei socket che possono
-applicarsi a qualunque tipo di socket,\footnote{una descrizione di queste
- opzioni è generalmente disponibile nella settima sezione delle pagine di
- manuale, nel caso specifico la si può consultare con \texttt{man 7 socket}.}
-indipendentemente da quale protocollo venga poi utilizzato. Se si vuole
-operare su queste opzioni generiche il livello da utilizzare è
-\const{SOL\_SOCKET}; si è riportato un elenco di queste opzioni in
-tab.~\ref{tab:sock_opt_socklevel}.
+applicarsi a qualunque tipo di socket, indipendentemente da quale protocollo
+venga poi utilizzato. Una descrizione di queste opzioni è generalmente
+disponibile nella settima sezione delle pagine di manuale; nel caso specifico
+la si può consultare con \texttt{man 7 socket}. Se si vuole operare su queste
+opzioni generiche il livello da utilizzare è \const{SOL\_SOCKET}; si è
+riportato un elenco di queste opzioni in tab.~\ref{tab:sock_opt_socklevel}.
\begin{table}[!htb]
\textbf{Descrizione}\\
\hline
\hline
+ \const{SO\_ACCEPTCONN}&$\bullet$& & &\texttt{int}&
+ Indica se il socket è in ascolto.\\
+ \const{SO\_ATTACH\_FILTER}& &$\bullet$& &\texttt{sock\_fprog}&
+ Aggancia un filtro BPF al socket.\\
+ \const{SO\_BINDTODEVICE}&$\bullet$&$\bullet$& &\texttt{char *}&
+ Lega il socket ad un dispositivo.\\
+ \const{SO\_BROADCAST}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Attiva o disattiva il \textit{broadcast}.\\
+ \const{SO\_BSDCOMPAT}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Abilita la compatibilità con BSD.\\
+ \const{SO\_BUSY\_POLL}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Attiva il ``\textit{busy poll}'' sul socket.\\
+ \const{SO\_DEBUG} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Abilita il debugging sul socket.\\
+ \const{SO\_DETACH\_FILTER}& &$\bullet$&$\bullet$&\texttt{int}&
+ Rimuove il filtro BPF agganciato al socket.\\
+ \const{SO\_DOMAIN} &$\bullet$& & &\texttt{int}&
+ Legge il tipo di socket.\\
+ \const{SO\_DONTROUTE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Non invia attraverso un gateway.\\
+ \const{SO\_ERROR} &$\bullet$& & &\texttt{int}&
+ Riceve e cancella gli errori pendenti.\\
\const{SO\_KEEPALIVE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
Controlla l'attività della connessione.\\
+ \const{SO\_LINGER} &$\bullet$&$\bullet$& &\texttt{linger}&
+ Indugia nella chiusura con dati da spedire.\\
+ \const{SO\_LOCK\_FILTER}& &$\bullet$&$\bullet$&\texttt{int}&
+ Blocca il filtro BPF agganciato al socket.\\
+ \const{SO\_MARK} &$\bullet$&$\bullet$& &\texttt{int}&
+ Imposta un ``\textit{firewall mark}'' sul socket.\\
\const{SO\_OOBINLINE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
Lascia in linea i dati \textit{out-of-band}.\\
- \const{SO\_RCVLOWAT} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
- Basso livello sul buffer di ricezione.\\
- \const{SO\_SNDLOWAT} &$\bullet$&$\bullet$& &\texttt{int}&
- Basso livello sul buffer di trasmissione.\\
- \const{SO\_RCVTIMEO} &$\bullet$&$\bullet$& &\texttt{timeval}&
- Timeout in ricezione.\\
- \const{SO\_SNDTIMEO} &$\bullet$&$\bullet$& &\texttt{timeval}&
- Timeout in trasmissione.\\
- \const{SO\_BSDCOMPAT}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
- Abilita la compatibilità con BSD.\\
\const{SO\_PASSCRED} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
Abilita la ricezione di credenziali.\\
+ \const{SO\_PEEK\_OFF} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Imposta il valore del ``\textit{peek offset}''.\\
\const{SO\_PEERCRED} &$\bullet$& & &\texttt{ucred}&
Restituisce le credenziali del processo remoto.\\
- \const{SO\_BINDTODEVICE}&$\bullet$&$\bullet$& &\texttt{char *}&
- Lega il socket ad un dispositivo.\\
- \const{SO\_DEBUG} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
- Abilita il debugging sul socket.\\
+ \const{SO\_PRIORITY} &$\bullet$&$\bullet$& &\texttt{int}&
+ Imposta la priorità del socket.\\
+ \const{SO\_PROTOCOL} &$\bullet$& & &\texttt{int}&
+ Ottiene il protocollo usato dal socket.\\
+ \const{SO\_RCVBUF} &$\bullet$&$\bullet$& &\texttt{int}&
+ Imposta dimensione del buffer di ricezione.\\
+ \const{SO\_RCVBUFFORCE}&$\bullet$&$\bullet$& &\texttt{int}&
+ Forza dimensione del buffer di ricezione.\\
+ \const{SO\_RCVLOWAT} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Basso livello sul buffer di ricezione.\\
+ \const{SO\_RCVTIMEO} &$\bullet$&$\bullet$& &\texttt{timeval}&
+ Timeout in ricezione.\\
\const{SO\_REUSEADDR}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
Consente il riutilizzo di un indirizzo locale.\\
- \const{SO\_TYPE} &$\bullet$& & &\texttt{int}&
- Restituisce il tipo di socket.\\
- \const{SO\_ACCEPTCONN}&$\bullet$& & &\texttt{int}&
- Indica se il socket è in ascolto.\\
- \const{SO\_DONTROUTE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
- Non invia attraverso un gateway.\\
- \const{SO\_BROADCAST}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
- Attiva o disattiva il \textit{broadcast}.\\
+ \const{SO\_REUSEPORT}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Consente il riutilizzo di una porta.\\
+ \const{SO\_RXQ\_OVFL} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Richiede messaggio ancillare con pacchetti persi.\\
\const{SO\_SNDBUF} &$\bullet$&$\bullet$& &\texttt{int}&
Imposta dimensione del buffer di trasmissione.\\
- \const{SO\_RCVBUF} &$\bullet$&$\bullet$& &\texttt{int}&
- Imposta dimensione del buffer di ricezione.\\
- \const{SO\_LINGER} &$\bullet$&$\bullet$& &\texttt{linger}&
- Indugia nella chiusura con dati da spedire.\\
- \const{SO\_PRIORITY} &$\bullet$&$\bullet$& &\texttt{int}&
- Imposta la priorità del socket.\\
- \const{SO\_ERROR} &$\bullet$& & &\texttt{int}&
- Riceve e cancella gli errori pendenti.\\
+ \const{SO\_SNDBUFFORCE}&$\bullet$&$\bullet$& &\texttt{int}&
+ Forza dimensione del buffer di trasmissione.\\
+ \const{SO\_SNDLOWAT} &$\bullet$&$\bullet$& &\texttt{int}&
+ Basso livello sul buffer di trasmissione.\\
+ \const{SO\_SNDTIMEO} &$\bullet$&$\bullet$& &\texttt{timeval}&
+ Timeout in trasmissione.\\
+ \const{SO\_TIMESTAMP}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Abilita/disabilita la ricezione dei \textit{timestamp}.\\
+ \const{SO\_TYPE} &$\bullet$& & &\texttt{int}&
+ Restituisce il tipo di socket.\\
\hline
\end{tabular}
\caption{Le opzioni disponibili al livello \const{SOL\_SOCKET}.}
% TODO aggiungere e documentare SO_ATTACH_BPF, introdotta con il kernel 3.19,
% vedi http://lwn.net/Articles/625224/
% TODO aggiungere e documentare SO_INCOMING_CPU, introdotta con il kernel 3.19,
-% vedi https://lwn.net/Articles/626150/
+% TODO documentare SO_PEERGROUPS introdotta con il kernel 4.13, citata
+% in https://lwn.net/Articles/727385/
+% TODO documentare SO_ZEROCOPY, vedi https://lwn.net/Articles/726917/ (e il
+% resto pure) introdotta con il kernel 4.14
La tabella elenca le costanti che identificano le singole opzioni da usare
come valore per \param{optname}; le due colonne seguenti indicano per quali
delle due funzioni (\func{getsockopt} o \func{setsockopt}) l'opzione è
-disponibile, mentre la colonna successiva indica, quando di ha a che fare con
+disponibile, mentre la colonna successiva indica, quando si ha a che fare con
un valore di \param{optval} intero, se l'opzione è da considerare un numero o
un valore logico. Si è inoltre riportato sulla quinta colonna il tipo di dato
usato per \param{optval} ed una breve descrizione del significato delle
separatamente in sez.~\ref{sec:sock_options_main}. Quello che segue è quindi
soltanto un elenco più dettagliato della breve descrizione di
tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni:
-\begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}}
-
-\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[\constd{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}. 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[\constd{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
- segnalando ad una \func{select} (vedi sez.~\ref{sec:TCP_sock_select}) che ci
- 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}.
-
-\item[\constd{SO\_SNDLOWAT}] questa opzione imposta il valore che indica il
- numero minimo di byte che devono essere presenti nel buffer di trasmissione
- perché il kernel li invii al protocollo successivo, consentendo ad una
- \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, 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[\constd{SO\_RCVTIMEO}] l'opzione permette di impostare un tempo massimo
- sulle operazioni di lettura da un socket, e prende per \param{optval} una
- struttura di tipo \struct{timeval} (vedi fig.~\ref{fig:sys_timeval_struct})
- 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.
-
- 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.\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 timeout per l'uso di \func{connect}, per avere
- il quale si può ricorrere a questa opzione.
-
-% TODO verificare il timeout con un programma di test
-
-\item[\constd{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{sendto} e \func{sendmsg}
- qualora queste restino bloccate per un tempo maggiore di quello specificato.
-
-\item[\constd{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.
-
- 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.
-\item[\constd{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.
+\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
+\item[\constd{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} ed utilizza per \param{optval} un intero in cui viene
+ restituito 1 se il socket è in ascolto e 0 altrimenti.
-\item[\constd{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}).
+\item[\constd{SO\_ATTACH\_FILTER}] questa opzione permette di agganciare ad un
+ socket un filtro di selezione dei pacchetti con la stessa sintassi del BPF
+ (\textit{Berkley Packet Filter}) di BSD, che consente di selezionare, fra
+ tutti quelli ricevuti, verranno letti. Può essere usata solo con
+ \func{setsockopt} ed utilizza per \param{optval} un puntatore ad una
+ struttura \struct{sock\_fprog} (definita in
+ \headfile{linux/filter.h}). Questa opzione viene usata principalmente con i
+ socket di tipo \const{AF\_PACKET} (torneremo su questo in
+ sez.~\ref{sec:packet_socket}) dalla libreria \texttt{libpcap} per
+ implementare programmi di cattura dei pacchetti, e per questo tipo di
+ applicazione è opportuno usare sempre quest'ultima.\footnote{la trattazione
+ del BPF va al di là dell'argomento di questa sezione per la documentazione
+ si consulti il file \texttt{networking/filter.txt} nella documentazione
+ del kernel.}
\item[\constd{SO\_BINDTODEVICE}] questa opzione permette di \textsl{legare} il
socket ad una particolare interfaccia, in modo che esso possa ricevere ed
famiglia \const{AF\_INET}; non è invece supportata per i \textit{packet
socket} (vedi sez.~\ref{sec:socket_raw}).
+\item[\constd{SO\_BROADCAST}] questa opzione abilita il \textit{broadcast}:
+ quando abilitata i socket di tipo \const{SOCK\_DGRAM} riceveranno i
+ pacchetti inviati all'indirizzo di \textit{broadcast} e potranno scrivere
+ pacchetti su tale indirizzo. Prende per \param{optval} un intero usato come
+ valore logico. L'opzione non ha effetti su un socket di tipo
+ \const{SOCK\_STREAM}.
+
+\item[\constd{SO\_BSDCOMPAT}] questa opzione abilita la compatibilità con il
+ comportamento di BSD (in particolare ne riproduce alcuni bug). Attualmente
+ è una opzione usata solo per il protocollo UDP e ne è prevista la rimozione.
+ L'opzione utilizza per \param{optval} un intero usato come valore logico.
+
+ Quando viene abilitata gli errori riportati da messaggi ICMP per un socket
+ UDP non vengono passati al programma in \textit{user space}. Con le versioni
+ 2.0.x del kernel erano anche abilitate altre opzioni di compatibilità per i
+ socket raw (modifiche casuali agli header, perdita del flag di
+ \textit{broadcast}) che sono state rimosse con il passaggio al 2.2; è
+ consigliato correggere i programmi piuttosto che usare questa funzione. Dal
+ kernel 2.4 viene ignorata, e dal 2.6 genera un messaggio di log del kernel.
+
+\item[\constd{SO\_BUSY\_POLL}] questa opzione, presente dal kernel 3.11,
+ imposta un tempo approssimato in microsecondi, per cui in caso di ricezione
+ bloccante verrà eseguito un \itindex{busy~poll} ``\textit{busy
+ poll}'',\footnote{con \textit{busy poll} si fa riferimento al
+ \textit{polling} su una risorsa occupata; si continuerà cioè a tentare di
+ leggere anche quando non ci sono dati senza portare il processo stato di
+ \textit{sleep}, in alcuni casi, quando ci si aspetta che i dati arrivino a
+ breve, questa tecnica può dare un miglioramento delle prestazioni.} da
+ indicare in \param{optval} con un valore intero. Si tratta di una opzione
+ utilizzabile solo con socket che ricevono dati da un dispositivo di rete che
+ la supporti, e che consente di ridurre la latenza per alcune applicazioni,
+ ma che comporta un maggiore utilizzo della CPU (e quindi di energia); per
+ questo il valore può essere aumentato solo da processi con i privilegi di
+ amministratore (in particolare con la \textit{capability}
+ \const{CAP\_NET\_ADMIN}). Il valore di default viene controllato dal file
+ \sysctlrelfile{net/core}{busy\_read} per le funzioni di lettura mentre il
+ file \sysctlrelfile{net/core}{busy\_poll} controlla il ``\textit{busy
+ poll}'' per \func{select} e \func{poll}.
+
\item[\constd{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
sulla rete su un buffer circolare che viene letto da un apposito
programma, \cmd{trpt}.}
-\item[\const{SO\_REUSEADDR}] questa opzione permette di eseguire la funzione
- \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. Maggiori dettagli sul suo funzionamento sono forniti in
- sez.~\ref{sec:sock_options_main}.
+\item[\constd{SO\_DETACH\_FILTER}] consente di distaccare un filtro
+ precedentemente aggiunto ad un socket con l'opzione
+ \const{SO\_ATTACH\_FILTER}, in genere non viene usata direttamente in quanto
+ i filtri BPF vengono automaticamente rimossi alla chiusura del socket, il
+ suo utilizzo è pertanto limitato ai rari casi in cui si vuole rimuovere un
+ precedente filtro per inserirne uno diverso. Come \const{SO\_ATTACH\_FILTER}
+ può essere usato solo \func{setsockopt} e prende per \param{optval} un
+ intero usato come valore logico.
+
+\item[\constd{SO\_DOMAIN}] questa opzione, presente dal kernel 2.6.32, legge
+ il ``\textsl{dominio}'' (la famiglia di indirizzi) del socket.
+. Funziona solo con \func{getsockopt}, ed
+ utilizza per \param{optval} un intero in cui verrà restituito il valore
+ numerico che lo identifica (ad esempio \texttt{AF\_INET}).
+
+\item[\constd{SO\_DONTROUTE}] questa opzione richiede che l'invio dei
+ pacchetti del socket sia eseguito soltanto verso una destinazione
+ direttamente connessa, impedendo l'uso di un \textit{gateway} e saltando
+ ogni processo relativo all'uso della tabella di routing del kernel. Prende
+ per \param{optval} un intero usato come valore logico. È equivalente all'uso
+ del flag \const{MSG\_DONTROUTE} su una \func{send} (vedi
+ sez.~\ref{sec:net_send_recv}).
-\item[\constd{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à restituito il valore numerico che lo
- identifica (ad esempio \const{SOCK\_STREAM}).
+\item[\constd{SO\_ERROR}] questa opzione riceve un errore presente sul socket;
+ può essere utilizzata soltanto con \func{getsockopt} e prende per
+ \param{optval} un valore intero, nel quale viene restituito il codice di
+ errore, e la condizione di errore sul socket viene cancellata. Viene
+ usualmente utilizzata per ricevere il codice di errore, come accennato in
+ sez.~\ref{sec:TCP_sock_select}, quando si sta osservando il socket con una
+ \func{select} che ritorna a causa dello stesso.
-\item[\constd{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.
+\item[\const{SO\_KEEPALIVE}] questa opzione abilita un meccanismo di verifica
+ della persistenza di una connessione associata al socket; è 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[\constd{SO\_DONTROUTE}] questa opzione forza l'invio diretto dei
- pacchetti del socket, saltando ogni processo relativo all'uso della tabella
- di routing del kernel. Prende per \param{optval} un intero usato come valore
+\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 \headfile{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[\constd{SO\_LOCK\_FILTER}] consente di bloccare un filtro
+ precedentemente aggiunto ad un socket con l'opzione
+ \const{SO\_ATTACH\_FILTER}, in modo che non possa essere né rimosso né
+ modificato, questo consente di impostare un filtro su un socket, bloccarlo e
+ poi cedere i privilegi con la sicurezza che il filtro permarrà fino alla
+ chiusura del socket. Come \const{SO\_ATTACH\_FILTER} può essere usato solo
+ \func{setsockopt} e prende per \param{optval} un intero usato come valore
logico.
-\item[\constd{SO\_BROADCAST}] questa opzione abilita il \textit{broadcast};
- quanto abilitata i socket di tipo \const{SOCK\_DGRAM} riceveranno i
- pacchetti inviati all'indirizzo di \textit{broadcast}, e potranno scrivere
- pacchetti su tale indirizzo. Prende per \param{optval} un intero usato come
- valore logico. L'opzione non ha effetti su un socket di tipo
- \const{SOCK\_STREAM}.
+\item[\constd{SO\_MARK}] questa opzione, presente dal kernel 2.6.25, imposta
+ un valore di marcatura sui pacchetti del socket. Questa è una funzionalità
+ specifica di Linux, ottenibile anche con l'uso del target \texttt{MARK}
+ del comando \texttt{iptables} (l'argomento è trattato in sez.~3.3.5 di
+ \cite{SGL}). Il valore di marcatura viene mantenuto all'interno dello stack
+ di rete del kernel e può essere usato sia dal \itindex{netfilter}
+ \textit{netfilter}\footnote{il \textit{netfilter} è l'infrastruttura usata
+ per il filtraggio dei pacchetti del kernel, per maggiori dettagli si
+ consulti il cap.~2 di \cite{FwGL}.} di Linux che per impostare politiche
+ di routing avanzato. Il valore deve essere specificato in \param{optval}
+ come un intero. L'opzione richiede i privilegi di amministratore con la
+ \textit{capability} \const{CAP\_NET\_ADMIN}.
-\item[\constd{SO\_SNDBUF}] questa opzione imposta la dimensione del buffer di
- trasmissione del socket. Prende per \param{optval} un intero indicante il
- numero di byte. Il valore di default ed il valore massimo che si possono
- specificare come argomento per questa opzione sono impostabili
- rispettivamente tramite gli opportuni valori di \func{sysctl} (vedi
- sez.~\ref{sec:sock_sysctl}).
+\item[\constd{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}. 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[\constd{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[\constd{SO\_PEEK\_OFF}] questa opzione, disponibile a partire dal kernel
+ 3.4, imposta un ``\textit{peek offset}'' sul socket (attualmente disponibile
+ solo per i socket unix-domain (vedi sez.~\ref{sec:unix_socket}). La funzione
+ serve come ausilio per l'uso del flag \const{MSG\_PEEK} di \func{recv} che
+ consente di ``\textsl{sbirciare}'' nei dati di un socket, cioè di leggerli
+ senza rimuoverli dalla coda in cui sono mantenuti, così che vengano
+ restituiti anche da una successiva lettura ordinaria.
+
+ Un valore negativo (il default è $-1$) riporta alla situazione ordinaria in
+ cui si ``\textsl{sbircia}'' a partire dalla testa della coda, un valore
+ positivo consente di leggere a partire dalla posizione indicata nella coda e
+ tutte le volte che si sbirciano dei dati il valore dell'offset viene
+ automaticamente aumentato della quantità di dati sbirciati, in modo che si
+ possa proseguire da dove si era arrivati. Il valore deve essere specificato
+ in \param{optval} come intero.
+
+\item[\constd{SO\_PEERCRED}] questa opzione restituisce le credenziali del
+ processo remoto connesso al socket; l'opzione è disponibile solo per socket
+ unix-domain di tipo \textit{stream} e anche per quelli di tipo
+ \textit{datagram} quando se ne crea una coppia con \func{socketpair}, e può
+ essere usata solo con \func{getsockopt}. Utilizza per
+ \param{optval} una apposita struttura \struct{ucred} (vedi
+ sez.~\ref{sec:unix_socket}).
+
+\item[\constd{SO\_PRIORITY}] questa opzione permette di impostare le priorità
+ per tutti i pacchetti che sono inviati sul socket, prende per \param{optval}
+ un valore intero. Con questa opzione il kernel usa il valore per ordinare le
+ priorità sulle code di rete,\footnote{questo richiede che sia abilitato il
+ sistema di \textit{Quality of Service} disponibile con le opzioni di
+ routing avanzato.} i pacchetti con priorità più alta vengono processati
+ per primi, in modalità che dipendono dalla disciplina di gestione della
+ coda. Nel caso di protocollo IP questa opzione permette anche di impostare i
+ valori del campo \textit{type of service} (noto come TOS, vedi
+ sez.~\ref{sec:IP_header}) per i pacchetti uscenti. Per impostare una
+ priorità al di fuori dell'intervallo di valori fra 0 e 6 sono richiesti i
+ privilegi di amministratore con la \textit{capability}
+ \const{CAP\_NET\_ADMIN}.
+
+\item[\constd{SO\_PROTOCOL}] questa opzione, presente dal kernel 2.6.32, legge
+ il protocollo usato dal socket. Funziona solo con \func{getsockopt}, ed
+ utilizza per \param{optval} un intero in cui verrà restituito il valore
+ numerico che lo identifica (ad esempio \texttt{IPPROTO\_TCP}).
\item[\constd{SO\_RCVBUF}] questa opzione imposta la dimensione del buffer di
ricezione del socket. Prende per \param{optval} un intero indicante il
specificare come argomento per questa opzione sono impostabili tramiti gli
opportuni valori di \func{sysctl} (vedi sez.~\ref{sec:sock_sysctl}).
- Si tenga presente che nel caso di socket TCP, per entrambe le opzioni
- \const{SO\_RCVBUF} e \const{SO\_SNDBUF}, il kernel alloca effettivamente una
- quantità di memoria doppia rispetto a quanto richiesto con
- \func{setsockopt}. Questo comporta che una successiva lettura con
+ Si tenga presente che nel caso di socket TCP il kernel alloca effettivamente
+ una quantità di memoria doppia rispetto a quanto richiesto con
+ \func{setsockopt} per entrambe le opzioni \const{SO\_RCVBUF} e
+ \const{SO\_SNDBUF}. Questo comporta che una successiva lettura con
\func{getsockopt} riporterà un valore diverso da quello impostato con
\func{setsockopt}. Questo avviene perché TCP necessita dello spazio in più
per mantenere dati amministrativi e strutture interne, e solo una parte
essere effettive, devono essere impostate prima della chiamata alle funzioni
\func{listen} o \func{connect}.
-\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 \headfile{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[\constd{SO\_RCVBUFFORCE}] questa opzione, presente dal kernel 2.6.14, è
+ identica a \const{SO\_RCVBUF} ma consente ad un processo con i privilegi di
+ amministratore (per la precisione con la \textit{capability}
+ \const{CAP\_NET\_ADMIN}) di impostare in valore maggiore del limite di
+ \sysctlrelfile{net/core}{rmem\_max}.
-\item[\constd{SO\_PRIORITY}] questa opzione permette di impostare le priorità
- per tutti i pacchetti che sono inviati sul socket, prende per \param{optval}
- un valore intero. Con questa opzione il kernel usa il valore per ordinare le
- priorità sulle code di rete,\footnote{questo richiede che sia abilitato il
- sistema di \textit{Quality of Service} disponibile con le opzioni di
- routing avanzato.} i pacchetti con priorità più alta vengono processati
- per primi, in modalità che dipendono dalla disciplina di gestione della
- coda. Nel caso di protocollo IP questa opzione permette anche di impostare i
- valori del campo \textit{type of service} (noto come TOS, vedi
- sez.~\ref{sec:IP_header}) per i pacchetti uscenti. Per impostare una
- priorità al di fuori dell'intervallo di valori fra 0 e 6 sono richiesti i
- privilegi di amministratore con la capability \const{CAP\_NET\_ADMIN}.
+\item[\constd{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
+ segnalando ad una \func{select} (vedi sez.~\ref{sec:TCP_sock_select}) che ci
+ sono dati in ingresso. L'opzione utilizza per \param{optval} un intero che
+ specifica il numero di byte; con Linux questo valore è sempre 1 e può essere
+ cambiato solo con i kernel a partire dal 2.4. Si tenga presente però che per
+ i kernel prima del 2.6.28 sia \func{poll} che \func{select} non supportano
+ questa funzionalità e ritornano comunque, indicando il socket come
+ leggibile, non appena almeno un byte è presente, con una successiva lettura
+ con \func{read} che si blocca fintanto che non diventa disponibile la
+ quantità di byte indicati. Con \func{getsockopt} si può leggere questo
+ valore mentre \func{setsockopt} darà un errore di \errcode{ENOPROTOOPT}
+ quando il cambiamento non è supportato.
-\item[\constd{SO\_ERROR}] questa opzione riceve un errore presente sul socket;
- può essere utilizzata soltanto con \func{getsockopt} e prende per
- \param{optval} un valore intero, nel quale viene restituito il codice di
- errore, e la condizione di errore sul socket viene cancellata. Viene
- usualmente utilizzata per ricevere il codice di errore, come accennato in
- sez.~\ref{sec:TCP_sock_select}, quando si sta osservando il socket con una
- \func{select} che ritorna a causa dello stesso.
+\item[\constd{SO\_RCVTIMEO}] l'opzione permette di impostare un tempo massimo
+ sulle operazioni di lettura da un socket, e prende per \param{optval} una
+ struttura di tipo \struct{timeval} (vedi fig.~\ref{fig:sys_timeval_struct})
+ 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.
-\item[\constd{SO\_ATTACH\_FILTER}] questa opzione permette di agganciare ad un
- socket un filtro di pacchetti che consente di selezionare quali pacchetti,
- fra tutti quelli ricevuti, verranno letti. Viene usato principalmente con i
- socket di tipo \const{PF\_PACKET} con la libreria \texttt{libpcap} per
- implementare programmi di cattura dei pacchetti, torneremo su questo in
- sez.~\ref{sec:packet_socket}.
+ 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.\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.}
-\item[\constd{SO\_DETACH\_FILTER}] consente di distaccare un filtro
- precedentemente aggiunto ad un socket.
+ 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 timeout per l'uso di \func{connect}, per avere
+ il quale si può ricorrere a questa opzione (nel qual caso il raggiungimento
+ del \textit{timeout} restituisce l'errore \errcode{EINPROGRESS}).
+
+\item[\const{SO\_REUSEADDR}] questa opzione permette di eseguire la funzione
+ \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 (più propriamente il
+ controllo viene eseguito sulla porta) è già in uso da parte di un altro
+ socket. Maggiori dettagli sul suo funzionamento sono forniti in
+ sez.~\ref{sec:sock_options_main}.
-% TODO documentare SO_ATTACH_FILTER e SO_DETACH_FILTER
-% riferimenti http://www.rcpt.to/lsfcc/lsf.html
-% Documentation/networking/filter.txt
+\item[\const{SO\_REUSEPORT}] questa opzione, presente a partire dal kernel
+ 3.9, permette di far usare a più socket di tipo \const{AF\_INET} o
+ \const{AF\_INET6} lo stesso indirizzo locale, e costituisce una estensione
+ della precedente \const{SO\_REUSEADDR}. Maggiori dettagli sul suo
+ funzionamento sono forniti in sez.~\ref{sec:sock_options_main}.
-% TODO documentare SO_MARK, introdotta nel 2.6.25, richiede CAP_NET_ADMIN
-%A userspace program may wish to set the mark for each packets its send
-%without using the netfilter MARK target. Changing the mark can be used
-%for mark based routing without netfilter or for packet filtering.
+\item[\constd{SO\_RXQ\_OVFL}] questa opzione, presente dal kernel 2.6.33,
+ permette di abilitare o disabilitare sul socket la ricezione di un messaggio
+ ancillare (tratteremo l'argomento in sez.~\ref{sec:net_ancillary_data})
+ contenente un intero senza segno a 32 bit che indica il numero di pacchetti
+ scartati sul socket fra l'ultimo pacchetto ricevuto e questo. L'opzione
+ utilizza per \param{optval} un intero usato come valore logico.
+% TODO documentare SO_RXQ_OVFL, vedi https://lwn.net/Articles/626150/ capire
+% che significa 'questo'
+\item[\constd{SO\_SNDLOWAT}] questa opzione imposta il valore che indica il
+ numero minimo di byte che devono essere presenti nel buffer di trasmissione
+ perché il kernel li invii al protocollo successivo, consentendo ad una
+ \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; 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[\constd{SO\_SNDBUF}] questa opzione imposta la dimensione del buffer di
+ trasmissione del socket. Prende per \param{optval} un intero indicante il
+ numero di byte. Il valore di default ed il valore massimo che si possono
+ specificare come argomento per questa opzione sono impostabili
+ rispettivamente tramite gli opportuni valori di \func{sysctl} (vedi
+ sez.~\ref{sec:sock_sysctl}).
+
+\item[\constd{SO\_SNDBUFFORCE}] questa opzione, presente dal kernel 2.6.14, è
+ identica a \const{SO\_SNDBUF} ma consente ad un processo con i privilegi di
+ amministratore (per la precisione con la \textit{capability}
+ \const{CAP\_NET\_ADMIN}) di impostare in valore maggiore del limite di
+ \sysctlrelfile{net/core}{wmem\_max}.
+
+% TODO verificare il timeout con un programma di test
+
+\item[\constd{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{sendto} e \func{sendmsg}
+ qualora queste restino bloccate per un tempo maggiore di quello specificato.
+
+\item[\constd{SO\_TIMESTAMP}] questa opzione, presente dal kernel 2.6.30,
+ permette di abilitare o disabilitare sul socket la ricezione di un messaggio
+ ancillare di tipo \const{SO\_TIMESTAMP}. Il messaggio viene inviato con
+ livello \const{SOL\_SOCKET} ed nel campo \var{cmsg\_data} (per i dettagli si
+ veda sez.~\ref{sec:net_ancillary_data}) viene impostata una struttura
+ \struct{timeval} che indica il tempo di ricezione dell'ultimo pacchetto
+ passato all'utente. L'opzione utilizza per \param{optval} un intero usato
+ come valore logico.
+
+% TODO capire meglio la tempistica di questi messaggi ancillari
% TODO documentare SO_TIMESTAMP e le altre opzioni di timestamping dei
% pacchetti, introdotte nel 2.6.30, vedi nei sorgenti del kernel:
% Documentation/networking/timestamping.txt
+\item[\constd{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à restituito il valore numerico che lo
+ identifica (ad esempio \const{SOCK\_STREAM}).
-% TOFO documentare SO_REUSEPORT introdotta con il kernel 3.9, vedi
-% http://git.kernel.org/linus/c617f398edd4db2b8567a28e899a88f8f574798d
\end{basedescript}
principalmente ai socket TCP.
Con le impostazioni di default (che sono riprese da BSD) Linux emette un
-messaggio di \textit{keep-alive}\footnote{in sostanza un segmento ACK vuoto,
- cui sarà risposto con un altro segmento ACK vuoto.} 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à; il tutto avviene all'interno del kernel e le applicazioni
-non riceveranno nessun dato.
+messaggio di \textit{keep-alive} (in sostanza un segmento ACK vuoto, cui sarà
+risposto con un altro segmento ACK vuoto) 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à;
+il tutto avviene all'interno del kernel e le applicazioni non riceveranno
+nessun dato.
Qualora ci siano dei problemi di rete si possono invece verificare i due casi
di terminazione precoce del server già illustrati in
Abilitandola dopo un certo tempo le connessioni effettivamente terminate
verranno comunque chiuse per cui, utilizzando ad esempio una \func{select}, se
-be potrà rilevare la conclusione e ricevere il relativo errore. Si tenga
+ne potrà rilevare la conclusione e ricevere il relativo errore. Si tenga
presente però che non può avere la certezza assoluta che un errore di
\errcode{ETIMEDOUT} ottenuto dopo aver abilitato questa opzione corrisponda
necessariamente ad una reale conclusione della connessione, il problema
\constbeg{SO\_REUSEADDR}
-\subsubsection{L'opzione \const{SO\_REUSEADDR}}
+\subsubsection{Le opzioni \const{SO\_REUSEADDR} e \const{SO\_REUSEPORT}}
-La seconda opzione da approfondire è \const{SO\_REUSEADDR}, che consente di
+La seconda opzione da approfondire è \constd{SO\_REUSEADDR}, che consente di
eseguire \func{bind} su un socket anche quando la porta specificata è già in
uso da parte di un altro socket. Si ricordi infatti che, come accennato in
sez.~\ref{sec:TCP_func_bind}, normalmente la funzione \func{bind} fallisce con
cui è prevista la possibilità di un utilizzo di questa opzione, il che la
rende una delle più difficili da capire.
-Il primo caso, che è anche il più comune, in cui si fa ricorso a
-\const{SO\_REUSEADDR} è quello in cui un server è terminato ma esistono ancora
-dei processi figli che mantengono attiva almeno una connessione remota che
-utilizza l'indirizzo locale, mantenendo occupata la porta. Quando si riesegue
-il server allora questo riceve un errore 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 trovarsi in questa situazione quando si sta
- sviluppando un server che si ferma e si riavvia in continuazione dopo aver
- fatto modifiche.} Inoltre se si usa il protocollo TCP questo può avvenire
-anche dopo tutti i processi figli sono terminati, dato che una connessione può
-restare attiva anche dopo la chiusura del socket, mantenendosi nello stato
-\texttt{TIME\_WAIT} (vedi sez.~\ref{sec:TCP_time_wait}).
+Il primo caso in cui si fa ricorso a \const{SO\_REUSEADDR}, che è anche il più
+comune, è quello in cui un server è terminato ma esistono ancora dei processi
+figli che mantengono attiva almeno una connessione remota che utilizza
+l'indirizzo locale, mantenendo occupata la porta. Quando si riesegue il server
+allora questo riceve un errore sulla chiamata a \func{bind} dato che la porta
+è ancora utilizzata in una connessione esistente.\footnote{questa è una delle
+ domande più frequenti relative allo sviluppo, in quanto è piuttosto comune
+ trovarsi in questa situazione quando si sta sviluppando un server che si
+ ferma e si riavvia in continuazione dopo aver fatto modifiche.} Inoltre se
+si usa il protocollo TCP questo può avvenire anche dopo tutti i processi figli
+sono terminati, dato che una connessione può restare attiva anche dopo la
+chiusura del socket, mantenendosi nello stato \texttt{TIME\_WAIT} (vedi
+sez.~\ref{sec:TCP_time_wait}).
+
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/sockbindopt.c}
+ \end{minipage}
+ \normalsize
+ \caption{Le sezioni della funzione \texttt{sockbindopt} modificate rispetto al
+ codice della precedente \texttt{sockbind}.}
+ \label{fig:sockbindopt_code}
+\end{figure}
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
socket, all'interno del file \texttt{SockUtils.c} dei sorgenti allegati alla
guida.
-\begin{figure}[!htbp]
- \footnotesize \centering
- \begin{minipage}[c]{\codesamplewidth}
- \includecodesample{listati/sockbindopt.c}
- \end{minipage}
- \normalsize
- \caption{Le sezioni della funzione \texttt{sockbindopt} modificate rispetto al
- codice della precedente \texttt{sockbind}.}
- \label{fig:sockbindopt_code}
-\end{figure}
-
In realtà tutto quello che si è fatto è stato introdurre nella nuova funzione
(\texttt{\small 1}) un nuovo argomento intero, \param{reuse}, che conterrà il
valore logico da usare nella successiva chiamata (\texttt{\small 14}) a
esegue l'impostazione dell'opzione fra la chiamata a \func{socket} e quella a
\func{bind}.
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/TCP_echod_fifth.c}
+ \end{minipage}
+ \normalsize
+ \caption{Il nuovo codice per l'apertura passiva del server \textit{echo} che
+ usa la nuova funzione \texttt{sockbindopt}.}
+ \label{fig:TCP_echod_fifth}
+\end{figure}
A questo punto basterà modificare il server per utilizzare la nuova
funzione; in fig.~\ref{fig:TCP_echod_fifth} abbiamo riportato le sezioni
valore, per cui in tal caso la successiva chiamata (\texttt{\small 13--17}) a
\func{setsockopt} attiverà l'opzione \const{SO\_REUSEADDR}.
-\begin{figure}[!htbp]
- \footnotesize \centering
- \begin{minipage}[c]{\codesamplewidth}
- \includecodesample{listati/TCP_echod_fifth.c}
- \end{minipage}
- \normalsize
- \caption{Il nuovo codice per l'apertura passiva del server \textit{echo} che
- usa la nuova funzione \texttt{sockbindopt}.}
- \label{fig:TCP_echod_fifth}
-\end{figure}
-
Il secondo caso in cui viene usata \const{SO\_REUSEADDR} è quando si ha una
-macchina cui sono assegnati diversi numeri IP (o come suol dirsi
+macchina cui sono assegnati diversi indirizzi 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}
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}.
+una precedente chiamata più specifica. Si tenga presente infatti che con il
+protocollo TCP non è in genere possibile far partire più server che eseguano
+\func{bind} sullo stesso indirizzo e la stessa porta se su di esso c'è già un
+socket in ascolto, cioè ottenere quello che viene chiamato un
+\itindex{completely~duplicate~binding} \textit{completely duplicate binding}
+(per questo è stata introdotta \const{SO\_REUSEPORT}).
Il terzo impiego è simile al precedente e prevede l'uso di \func{bind}
all'interno dello stesso programma per associare indirizzi locali diversi a
Infine il quarto caso è quello in cui 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 \textit{multicast}, allora ha senso
-che su una macchina i pacchetti provenienti dal traffico in \textit{multicast}
-possano essere ricevuti da più applicazioni\footnote{l'esempio classico di
- traffico in \textit{multicast} è quello di uno streaming di dati (audio,
- video, ecc.), l'uso del \textit{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
+\func{bind} su un indirizzo ed una porta che sono già ``\textsl{legati}'' ad
+un altro socket. Come accennato questo con TCP non è possibile, ed ha anche
+poco senso pensare di mettere in ascolto due server sulla stessa porta. Se
+però si prende in considerazione il traffico in \textit{multicast}, diventa
+assolutamente normale che i pacchetti provenienti dal traffico in
+\textit{multicast} possano essere ricevuti da più applicazioni o da diverse
+istanze della stessa applicazione sulla stessa porte di un indirizzo di
+\textit{multicast}.
+
+Un esempio classico è quello di uno streaming di dati (audio, video, ecc.) in
+cui l'uso del \textit{multicast} consente di trasmettere un solo pacchetto da
+recapitare a 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, e quindi effettuare un \textit{completely duplicate
+ binding}.
+
+In questo caso utilizzando \const{SO\_REUSEADDR} si può consentire 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 protocollo UDP). La regola è che quando si
+un'altra, così che anche essa possa ricevere gli stessi pacchetti. Come detto
+la cosa non è possibile con i socket TCP (per i quali il \textit{multicast}
+comunque non è applicabile), ma lo è per quelli UDP che è il protocollo
+normalmente in uso da parte di queste applicazioni. La regola è che quando si
hanno più applicazioni che hanno eseguito \func{bind} sulla stessa porta, di
tutti pacchetti destinati ad un indirizzo di \textit{broadcast} o di
-\textit{multicast} viene inviata una copia a ciascuna applicazione. Non è
+\textit{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
-esisteva fino al kernel 3.9, 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 programma che ha eseguito per primo
-\func{bind} su di essi ha impostato questa opzione.\footnote{questa
- restrizione permette di evitare parzialmente 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}.}
+normale (\textit{unicast}).
+
+% TODO documentare SO_REUSEPORT, vedi https://lwn.net/Articles/542260/
+\constbeg{SO\_REUSEPORT}
+
+Esistono però dei casi, in particolare per l'uso di programmi
+\textit{multithreaded}, in cui può servire un \textit{completely duplicate
+ binding} anche per delle ordinarie connessioni TCP. Per supportare queste
+esigenze a partire dal kernel 3.9 è stata introdotta un'altra opzione,
+\const{SO\_REUSEPORT} (già presente in altri sistemi come BSD), che consente
+di eseguire il \textit{completely duplicate binding}, fintanto che essa venga
+specificata per tutti i socket interessati. Come per \const{SO\_REUSEADDR}
+sarà possibile usare l'opzione su un socket legato allo stesso indirizzo e
+porta solo se il programma che ha eseguito il primo \func{bind} ha impostato
+questa opzione.
+
+Nel caso di \const{SO\_REUSEPORT} oltre al fatto che l'opzione deve essere
+attivata sul socket prima di chiamare \func{bind} ed attiva su tutti i socket
+con \textit{completely duplicate binding}, è richiesto pure che tutti i
+processi che si mettono in ascolto sullo stesso indirizzo e porta abbiano lo
+stesso \ids{UID} effettivo, per evitare che un altro utente possa ottenere il
+relativo traffico (eseguendo quello che viene definito \textit{port hijacking}
+o \textit{port stealing}). L'opzione utilizza per \param{optval} un intero
+usato come valore logico.
+
+L'opzione si usa sia per socket TCP che UDP, nel primo caso consente un uso
+distribuito di \func{accept} in una applicazione \textit{multithreaded}
+passando un diverso \textit{listening socket} ad ogni thread, cosa che
+migliora le prestazioni rispetto all'approccio tradizionale di usare un thread
+per usare \func{accept} e distribuire le connessioni agli altri o avere più
+thread che competono per usare \func{accept} sul socket. Nel caso di UDP
+l'opzione consente di distribuire meglio i pacchetti su più processi o thread,
+rispetto all'approccio tradizionale di far competere gli stessi per l'accesso
+in ricezione al socket.
+
+% TODO documentare SO_REUSEPORT introdotta con il kernel 3.9, vedi
+% http://git.kernel.org/linus/c617f398edd4db2b8567a28e899a88f8f574798d TODO:
+% in cosa differisce da REUSEADDR?
+
+\constend{SO\_REUSEPORT}
\constend{SO\_REUSEADDR}
-% TODO documentare SO_REUSEPORT, vedi https://lwn.net/Articles/542260/
\constbeg{SO\_LINGER}
\subsubsection{L'opzione \const{SO\_LINGER}}
\subsection{Le opzioni per il protocollo IPv4}
\label{sec:sock_ipv4_options}
-Il secondo insieme di opzioni dei socket che tratteremo è quello relativo ai
-socket che usano il protocollo IPv4.\footnote{come per le precedenti opzioni
- generiche una descrizione di esse è disponibile nella settima sezione delle
- pagine di manuale, nel caso specifico la documentazione si può consultare
- con \texttt{man 7 ip}.} Se si vuole operare su queste opzioni generiche il
-livello da utilizzare è \const{SOL\_IP} (o l'equivalente
-\constd{IPPROTO\_IP}); si è riportato un elenco di queste opzioni in
-tab.~\ref{tab:sock_opt_iplevel}. Le costanti indicanti le opzioni e tutte le
-altre costanti ad esse collegate sono definite in \headfiled{netinet/ip.h}, ed
-accessibili includendo detto file.
+Il secondo insieme di opzioni dei socket che tratteremo è quello relativo ai
+socket che usano il protocollo IPv4; come per le precedenti opzioni generiche
+una descrizione di esse è disponibile nella settima sezione delle pagine di
+manuale, nel caso specifico la documentazione si può consultare con
+\texttt{man 7 ip}.
+
+\begin{table}[!htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|c|c|c|l|p{4.8cm}|}
+ \hline
+ \textbf{Opzione}&\texttt{get}&\texttt{set}&\textbf{flag}&\textbf{Tipo}&
+ \textbf{Descrizione}\\
+ \hline
+ \hline
+ \const{IP\_ADD\_MEMBERSHIP} & &$\bullet$& &\struct{ip\_mreqn}&
+ Si unisce a un gruppo di \textit{multicast}.\\
+ \const{IP\_ADD\_SOURCE\_MEMBERSHIP} & &$\bullet$& &\struct{ip\_mreq\_source}&
+ Si unisce a un gruppo di \textit{multicast} per una sorgente.\\
+ \const{IP\_BLOCK\_SOURCE} & &$\bullet$& &\struct{ip\_mreq\_source}&
+ Smette di ricevere dati di \textit{multicast} per una sorgente.\\
+ \const{IP\_DROP\_MEMBERSHIP}& &$\bullet$& &\struct{ip\_mreqn}&
+ Si sgancia da un gruppo di \textit{multicast}.\\
+ \const{IP\_DROP\_SOURCE\_MEMBERSHIP}& &$\bullet$& &\struct{ip\_mreq\_source}&
+ Si sgancia da un gruppo di \textit{multicast} per una sorgente.\\
+ \const{IP\_FREEBIND} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Abilita il \textit{binding} a un indirizzo IP non locale ancora non assegnato.\\
+ \const{IP\_HDRINCL} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Passa l'intestazione di IP nei dati.\\
+ \const{IP\_MINTTL} &$\bullet$&$\bullet$& &\texttt{int}&
+ Imposta il valore minimo del TTL per i pacchetti accettati.\\
+ \const{IP\_MSFILTER} &$\bullet$&$\bullet$& &\struct{ip\_msfilter}&
+ Accesso completo all'interfaccia per il filtraggio delle sorgenti
+ \textit{multicast}.\\
+ \const{IP\_MTU} &$\bullet$& & &\texttt{int}&
+ Legge il valore attuale della MTU.\\
+ \const{IP\_MTU\_DISCOVER} &$\bullet$&$\bullet$& &\texttt{int}&
+ Imposta il \textit{Path MTU Discovery}.\\
+ \const{IP\_MULTICAST\_ALL} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Imposta l'interfaccia locale di un socket \textit{multicast}.\\
+ \const{IP\_MULTICAST\_IF} & &$\bullet$& &\struct{ip\_mreqn}&
+ Imposta l'interfaccia locale di un socket \textit{multicast}.\\
+ \const{IP\_MULTICAST\_LOOP} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Controlla il reinvio a se stessi dei dati di \textit{multicast}.\\
+ \const{IP\_MULTICAST\_TTL} &$\bullet$&$\bullet$& &\texttt{int}&
+ Imposta il TTL per i pacchetti \textit{multicast}.\\
+ \const{IP\_NODEFRAG} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Disabilita il riassemblaggio di pacchetti frammentati.\\
+ \const{IP\_OPTIONS} &$\bullet$&$\bullet$&&\texttt{void *}& %???
+ Imposta o riceve le opzioni di IP.\\
+ \const{IP\_PKTINFO} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Abilita i messaggi di informazione.\\
+ \const{IP\_RECVERR} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Abilita i messaggi di errore affidabili.\\
+ \const{IP\_RECVOPTS} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Passa un messaggio con le opzioni IP.\\
+ \const{IP\_RECVORIGSTADDR} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Abilita i messaggi con l'indirizzo di destinazione originale.\\
+ \const{IP\_RECVTOS} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Passa un messaggio col campo TOS.\\
+ \const{IP\_RECVTTL} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Abilita i messaggi col campo TTL.\\
+ \const{IP\_RETOPTS} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Abilita i messaggi con le opzioni IP non trattate.\\
+ \const{IP\_ROUTER\_ALERT} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Imposta l'opzione \textit{IP router alert} sui pacchetti.\\
+ \const{IP\_TOS} &$\bullet$&$\bullet$& &\texttt{int}&
+ Imposta il valore del campo TOS.\\
+ \const{IP\_TRANSPARENT} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Abilita un \textit{proxing} trasparente sul socket.\\
+ \const{IP\_TTL} &$\bullet$&$\bullet$& &\texttt{int}&
+ Imposta il valore del campo TTL.\\
+ \const{IP\_UNBLOCK\_SOURCE} & &$\bullet$& &\struct{ip\_mreq\_source}&
+ Ricomincia a ricevere dati di \textit{multicast} per una sorgente.\\
+ \hline
+ \end{tabular}
+ \caption{Le opzioni disponibili al livello \const{IPPROTO\_IP}.}
+ \label{tab:sock_opt_iplevel}
+\end{table}
+
+Se si vuole operare su queste opzioni generiche il livello da utilizzare è
+\constd{IPPROTO\_IP} (o l'equivalente \const{SOL\_IP}); si è riportato un
+elenco di queste opzioni in tab.~\ref{tab:sock_opt_iplevel}. Le costanti
+indicanti le opzioni, e tutte le altre costanti ad esse collegate, sono
+definite in \headfiled{netinet/ip.h}, ed accessibili includendo detto file.
+
+Le descrizioni riportate in tab.~\ref{tab:sock_opt_iplevel} sono estremamente
+succinte, una maggiore quantità di dettagli sulle varie opzioni è fornita nel
+seguente elenco:
+\begin{basedescript}{\desclabelwidth{2.0cm}\desclabelstyle{\nextlinelabel}}
+\item[\constd{IP\_ADD\_MEMBERSHIP}] L'opzione consente di unirsi ad gruppo di
+ \textit{multicast}, e può essere usata solo con \func{setsockopt}.
+ L'argomento \param{optval} in questo caso deve essere una struttura di tipo
+ \struct{ip\_mreqn}, illustrata in fig.~\ref{fig:ip_mreqn_struct}, che
+ permette di indicare, con il campo \var{imr\_multiaddr} l'indirizzo del
+ gruppo di \textit{multicast} a cui ci si vuole unire, con il campo
+ \var{imr\_address} l'indirizzo dell'interfaccia locale con cui unirsi al
+ gruppo di \textit{multicast} e con \var{imr\_ifindex} l'indice
+ dell'interfaccia da utilizzare (un valore nullo indica una interfaccia
+ qualunque).
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{0.90\textwidth}
+ \includestruct{listati/ip_mreqn.h}
+ \end{minipage}
+ \caption{La struttura \structd{ip\_mreqn} utilizzata per unirsi a un gruppo di
+ \textit{multicast}.}
+ \label{fig:ip_mreqn_struct}
+\end{figure}
+
+Questa struttura è presente a partire dal kernel 2.2, per compatibilità è
+possibile utilizzare anche un argomento di tipo \struct{ip\_mreq}, presente
+fino dal kernel 1.2, che differisce da essa soltanto per l'assenza del campo
+\var{imr\_ifindex}; il kernel riconosce il tipo di struttura in base alla
+differente dimensione passata in \param{optlen}.
+
+\item[\constd{IP\_ADD\_SOURCE\_MEMBERSHIP}] L'opzione consente di unirsi ad
+ gruppo di \textit{multicast}, ricevendo i dati solo da una sorgente
+ specifica; come \const{IP\_ADD\_MEMBERSHIP} può essere usata solo con
+ \func{setsockopt}.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{0.90\textwidth}
+ \includestruct{listati/ip_mreq_source.h}
+ \end{minipage}
+ \caption{La struttura \structd{ip\_mreqn} utilizzata per unirsi a un gruppo di
+ \textit{multicast} per una specifica sorgente.}
+ \label{fig:ip_mreq_source_struct}
+\end{figure}
+
+L'argomento \param{optval} in questo caso è una struttura
+\struct{ip\_mreq\_source} illustrata in fig.~\ref{fig:ip_mreq_source_struct},
+dove il campo \var{imr\_multiaddr} è l'indirizzo del gruppo di
+\textit{multicast}, il campo \var{imr\_interface} l'indirizzo dell'interfaccia
+locale che deve essere usata per aggiungersi al gruppo di \textit{multicast} e
+il campo \var{imr\_sourceaddr} l'indirizzo della sorgente da cui
+l'applicazione vuole ricevere i dati. L'opzione può essere ripetuta più volte
+per collegarsi a diverse sorgenti.
+
+\item[\constd{IP\_BLOCK\_SOURCE}] Questa opzione, disponibile dal kernel
+ 2.4.22, consente di smettere di ricevere dati di \textit{multicast} dalla
+ sorgente (e relativo gruppo) specificati dalla struttura
+ \struct{ip\_mreq\_source} (vedi fig.~\ref{fig:ip_mreq_source_struct})
+ passata come argomento \param{optval}. L'opzione è utilizzabile solo se si è
+ già registrati nel gruppo di \textit{multicast} indicato con un precedente
+ utilizzo di \const{IP\_ADD\_MEMBERSHIP} o
+ \const{IP\_ADD\_SOURCE\_MEMBERSHIP}.
+
+\item[\constd{IP\_DROP\_MEMBERSHIP}] Lascia un gruppo di \textit{multicast},
+ prende per \param{optval} la stessa struttura \struct{ip\_mreqn} (o
+ \struct{ip\_mreq}) usata per \const{IP\_ADD\_MEMBERSHIP} (vedi
+ fig.~\ref{fig:ip_mreqn_struct}).
+
+\item[\constd{IP\_DROP\_SOURCE\_MEMBERSHIP}] Lascia un gruppo di
+ \textit{multicast} per una specifica sorgente, prende per \param{optval} la
+ stessa struttura \struct{ip\_mreq\_source} usata per
+ \const{IP\_ADD\_SOURCE\_MEMBERSHIP} (vedi
+ fig.~\ref{fig:ip_mreq_source_struct}). Se ci si è registrati per più
+ sorgenti nello stesso gruppo, si continuerà a ricevere dati sulle altre. Per
+ smettere di ricevere dati da tutte le sorgenti occorre usare l'opzione
+ \const{IP\_LEAVE\_GROUP}.
+
+\item[\constd{IP\_FREEBIND}] Se abilitata questa opzione, disponibile dal
+ kernel 2.4, consente di usare \func{bind} anche su un indirizzo IP non
+ locale o che ancora non è stato assegnato. Questo permette ad una
+ applicazione di mettersi in ascolto su un socket prima che l'interfaccia
+ sottostante o l'indirizzo che questa deve usare sia stato configurato. È
+ l'equivalente a livello di singolo socket dell'uso della \textit{sysctl}
+ \texttt{ip\_nonlocal\_bind} che vedremo in
+ sez.~\ref{sec:sock_ipv4_sysctl}. Prende per
+ \param{optval} un intero usato come valore logico.
+
+\item[\constd{IP\_HDRINCL}] Se viene abilitata questa opzione, presente dal
+ kernel 2.0, l'utente deve fornire lui stesso l'intestazione del protocollo
+ IP in testa ai propri dati. L'opzione è valida soltanto per socket di tipo
+ \const{SOCK\_RAW}, e quando utilizzata eventuali valori impostati con
+ \const{IP\_OPTIONS}, \const{IP\_TOS} o \const{IP\_TTL} sono ignorati. In
+ ogni caso prima della spedizione alcuni campi dell'intestazione vengono
+ comunque modificati dal kernel, torneremo sull'argomento in
+ sez.~\ref{sec:socket_raw}. Prende per \param{optval} un intero usato come
+ valore logico.
+
+\item[\constd{IP\_MSFILTER}] L'opzione, introdotta con il kernel 2.4.22,
+ fornisce accesso completo all'interfaccia per il filtraggio delle sorgenti
+ di \textit{multicast} (il cosiddetto \textit{multicast source filtering},
+ definito dall'\href{http://www.ietf.org/rfc/rfc3376.txt}{RFC~3376}).
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{0.90\textwidth}
+ \includestruct{listati/ip_msfilter.h}
+ \end{minipage}
+ \caption{La struttura \structd{ip\_msfilter} utilizzata per il
+ \textit{multicast source filtering}.}
+ \label{fig:ip_msfilter_struct}
+\end{figure}
+
+L'argomento \param{optval} deve essere una struttura di tipo
+\struct{ip\_msfilter} (illustrata in fig.~\ref{fig:ip_msfilter_struct}); il
+campo \var{imsf\_multiaddr} indica l'indirizzo del gruppo di
+\textit{multicast}, il campo \var{imsf\_interface} l'indirizzo
+dell'interfaccia locale, il campo \var{imsf\_mode} indica la modalità di
+filtraggio e con i campi \var{imsf\_numsrc} e \var{imsf\_slist}
+rispettivamente la lunghezza della lista, e la lista stessa, degli indirizzi
+sorgente.
+
+Come ausilio all'uso di questa opzione sono disponibili le macro
+\macro{MCAST\_INCLUDE} e \macro{MCAST\_EXCLUDE} che si possono usare per
+\var{imsf\_mode}. Inoltre si può usare la macro
+\macro{IP\_MSFILTER\_SIZE}\texttt{(\textsf{n})} per determinare il valore
+di \param{optlen} con una struttura \struct{ip\_msfilter} contenente
+\texttt{\textsf{n}} sorgenti in \var{imsf\_slist}.
+
+\item[\constd{IP\_MINTTL}] L'opzione, introdotta con il kernel 2.6.34, imposta
+ un valore minimo per il campo \textit{Time to Live} dei pacchetti associati
+ al socket su cui è attivata, che se non rispettato ne causa lo scarto
+ automatico. L'opzione è nata per implementare
+ l'\href{http://www.ietf.org/rfc/rfc5082.txt}{RFC~5082} che la prevede come
+ forma di protezione per i router che usano il protocollo BGP poiché questi,
+ essendo in genere adiacenti, possono, impostando un valore di 255, scartare
+ automaticamente tutti gli eventuali pacchetti falsi creati da un attacco a
+ questo protocollo, senza doversi curare di verificarne la
+ validità.\footnote{l'attacco viene in genere portato per causare un
+ \textit{Denial of Service} aumentando il consumo di CPU del router nella
+ verifica dell'autenticità di un gran numero di pacchetti falsi; questi,
+ arrivando da sorgenti diverse da un router adiacente, non potrebbero più
+ avere un TTL di 255 anche qualora questo fosse stato il valore di
+ partenza, e l'impostazione dell'opzione consente di scartarli senza carico
+ aggiuntivo sulla CPU (che altrimenti dovrebbe calcolare una checksum).}
+
+\itindbeg{Path~MTU}
+\item[\constd{IP\_MTU}] Permette di leggere il valore della \textit{Path MTU}
+ del socket. L'opzione richiede per \param{optval} un intero che conterrà il
+ valore della \textit{Path MTU} in byte. Questa è una opzione introdotta con
+ i kernel della serie 2.2.x, ed è specifica di Linux.
+
+ È tramite questa opzione che un programma può leggere, quando si è avuto un
+ errore di \errval{EMSGSIZE}, il valore della MTU corrente del socket. Si
+ tenga presente che per poter usare questa opzione, oltre ad avere abilitato
+ la scoperta della \textit{Path MTU}, occorre che il socket sia stato
+ esplicitamente connesso con \func{connect}.
+
+ Ad esempio con i socket UDP si può ottenere una stima iniziale della
+ \textit{Path MTU} eseguendo prima una \func{connect} verso la destinazione,
+ e poi usando \func{getsockopt} con questa opzione. Si può anche avviare
+ esplicitamente il procedimento di scoperta inviando un pacchetto di grosse
+ dimensioni (che verrà scartato) e ripetendo l'invio coi dati aggiornati. Si
+ tenga infine conto che durante il procedimento i pacchetti iniziali possono
+ essere perduti, ed è compito dell'applicazione gestirne una eventuale
+ ritrasmissione.
+
+\item[\constd{IP\_MTU\_DISCOVER}] Questa è una opzione introdotta con i kernel
+ della serie 2.2.x, ed è specifica di Linux. L'opzione permette di scrivere
+ o leggere le impostazioni della modalità usata per la determinazione della
+ \textit{Path MTU} (vedi sez.~\ref{sec:net_lim_dim}) del
+ socket. L'opzione prende per \param{optval} un valore intero che indica la
+ modalità usata, da specificare con una delle costanti riportate in
+ tab.~\ref{tab:sock_ip_mtu_discover}.
+
+ \begin{table}[!htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|r|p{7cm}|}
+ \hline
+ \multicolumn{2}{|c|}{\textbf{Valore}}&\textbf{Significato} \\
+ \hline
+ \hline
+ \constd{IP\_PMTUDISC\_DONT}&0& Non effettua la ricerca dalla \textit{Path
+ MTU}.\\
+ \constd{IP\_PMTUDISC\_WANT}&1& Utilizza il valore impostato per la rotta
+ utilizzata dai pacchetti (dal comando
+ \texttt{route}).\\
+ \constd{IP\_PMTUDISC\_DO} &2& Esegue la procedura di determinazione
+ della \textit{Path MTU} come richiesto
+ dall'\href{http://www.ietf.org/rfc/rfc1191.txt}{RFC~1191}.\\
+ \constd{IP\_PMTUDISC\_PROBE}&?& .\\
+ \hline
+ \end{tabular}
+ \caption{Valori possibili per l'argomento \param{optval} di
+ \const{IP\_MTU\_DISCOVER}.}
+ \label{tab:sock_ip_mtu_discover}
+ \end{table}
+
+ Il valore di default applicato ai socket di tipo \const{SOCK\_STREAM} è
+ determinato dal parametro \texttt{ip\_no\_pmtu\_disc} (vedi
+ sez.~\ref{sec:sock_sysctl}), mentre per tutti gli altri socket di default la
+ ricerca è disabilitata ed è responsabilità del programma creare pacchetti di
+ dimensioni appropriate e ritrasmettere eventuali pacchetti persi. Se
+ l'opzione viene abilitata, il kernel si incaricherà di tenere traccia
+ automaticamente della \textit{Path MTU} verso ciascuna destinazione, e
+ rifiuterà immediatamente la trasmissione di pacchetti di dimensioni maggiori
+ della MTU con un errore di \errval{EMSGSIZE}.\footnote{in caso contrario la
+ trasmissione del pacchetto sarebbe effettuata, ottenendo o un fallimento
+ successivo della trasmissione, o la frammentazione dello stesso.}
+\itindend{Path~MTU}
+
+\item[\constd{IP\_MULTICAST\_IF}] Imposta l'interfaccia locale per l'utilizzo
+ del \textit{multicast}, ed utilizza come \param{optval} le stesse strutture
+ \struct{ip\_mreqn} o \struct{ip\_mreq} delle due precedenti opzioni.
-\begin{table}[!htb]
- \centering
- \footnotesize
- \begin{tabular}[c]{|l|c|c|c|l|p{6cm}|}
- \hline
- \textbf{Opzione}&\texttt{get}&\texttt{set}&\textbf{flag}&\textbf{Tipo}&
- \textbf{Descrizione}\\
- \hline
- \hline
- \const{IP\_OPTIONS} &$\bullet$&$\bullet$&&\texttt{void *}& %???
- 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$& &\texttt{int}&
- Imposta il valore del campo TOS.\\
- \const{IP\_TTL} &$\bullet$&$\bullet$& &\texttt{int}&
- Imposta il valore del campo TTL.\\
- \const{IP\_MINTTL} &$\bullet$&$\bullet$& &\texttt{int}&
- Imposta il valore minimo del TTL per i pacchetti accettati.\\
- \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$& &\texttt{int}&
- Imposta il \textit{Path MTU Discovery}.\\
- \const{IP\_MTU} &$\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$& &\texttt{int}&
- Imposta il TTL per i pacchetti \textit{multicast}.\\
- \const{IP\_MULTICAST\_LOOP} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
- Controlla il reinvio a se stessi dei dati di \textit{multicast}.\\
- \const{IP\_ADD\_MEMBERSHIP} & &$\bullet$& &\struct{ip\_mreqn}&
- Si unisce a un gruppo di \textit{multicast}.\\
- \const{IP\_DROP\_MEMBERSHIP}& &$\bullet$& &\struct{ip\_mreqn}&
- Si sgancia da un gruppo di \textit{multicast}.\\
- \const{IP\_MULTICAST\_IF} & &$\bullet$& &\struct{ip\_mreqn}&
- Imposta l'interfaccia locale di un socket \textit{multicast}.\\
- \hline
- \end{tabular}
- \caption{Le opzioni disponibili al livello \const{SOL\_IP}.}
- \label{tab:sock_opt_iplevel}
-\end{table}
+\item[\constd{IP\_MULTICAST\_LOOP}] L'opzione consente di decidere se i dati
+ che si inviano su un socket usato con il \textit{multicast} vengano ricevuti
+ anche sulla stessa macchina da cui li si stanno inviando. Prende per
+ \param{optval} un intero usato come valore logico.
-Le descrizioni riportate in tab.~\ref{tab:sock_opt_iplevel} sono estremamente
-succinte, una maggiore quantità di dettagli sulle varie opzioni è fornita nel
-seguente elenco:
-\begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}}
+ 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 in locale l'uso di questa opzione permette di disabilitare
+ questo tipo di traffico.
+\item[\constd{IP\_MULTICAST\_TTL}] L'opzione permette di impostare o leggere il
+ valore del campo TTL per i pacchetti \textit{multicast} in uscita associati
+ al socket. È importante che questo valore sia il più basso possibile, ed il
+ default è 1, che significa che i pacchetti non potranno uscire dalla rete
+ locale. Questa opzione consente ai programmi che lo richiedono di superare
+ questo limite. L'opzione richiede per
+ \param{optval} un intero che conterrà il valore del TTL.
+% TODO chiarire quale è la struttura \struct{ip\_mreq}
\item[\constd{IP\_OPTIONS}] l'opzione permette di impostare o leggere le
opzioni del protocollo IP (si veda sez.~\ref{sec:IP_options}). L'opzione
opzione richiede una profonda conoscenza del funzionamento del protocollo,
torneremo in parte sull'argomento in sez.~\ref{sec:sock_IP_options}.
-
\item[\constd{IP\_PKTINFO}] Quando abilitata l'opzione permette di ricevere
insieme ai pacchetti un messaggio ancillare (vedi
sez.~\ref{sec:net_ancillary_data}) di tipo \const{IP\_PKTINFO} contenente
letto o scritto direttamente con \func{recvmsg} e \func{sendmsg} (vedi
sez.~\ref{sec:net_sendmsg}).
+\item[\constd{IP\_RECVERR}] Questa è una opzione introdotta con i kernel della
+ serie 2.2.x, ed è specifica di Linux. Essa permette di usufruire di un
+ meccanismo affidabile per ottenere un maggior numero di informazioni in caso
+ di errori. Se l'opzione è abilitata tutti gli errori generati su un socket
+ vengono memorizzati su una coda, dalla quale poi possono essere letti con
+ \func{recvmsg} (vedi sez.~\ref{sec:net_sendmsg}) come messaggi ancillari
+ (torneremo su questo in sez.~\ref{sec:net_ancillary_data}) di tipo
+ \const{IP\_RECVERR}. L'opzione richiede per \param{optval} un intero usato
+ come valore logico e non è applicabile a socket di tipo
+ \const{SOCK\_STREAM}.
+
+\item[\constd{IP\_RECVOPTS}] Quando abilitata l'opzione permette di ricevere
+ insieme ai pacchetti un messaggio ancillare (vedi
+ sez.~\ref{sec:net_ancillary_data}) di tipo \const{IP\_OPTIONS}, contenente
+ le opzioni IP del protocollo (vedi sez.~\ref{sec:IP_options}). Le
+ intestazioni di instradamento e le altre opzioni sono già riempite con i
+ dati locali. L'opzione richiede per \param{optval} un intero usato come
+ valore logico. L'opzione non è supportata per socket di tipo
+ \const{SOCK\_STREAM}.
\item[\constd{IP\_RECVTOS}] Quando abilitata l'opzione permette di ricevere
insieme ai pacchetti un messaggio ancillare (vedi
intero usato come valore logico. L'opzione non è supportata per socket di
tipo \const{SOCK\_STREAM}.
-\item[\constd{IP\_RECVOPTS}] Quando abilitata l'opzione permette di ricevere
- insieme ai pacchetti un messaggio ancillare (vedi
- sez.~\ref{sec:net_ancillary_data}) di tipo \const{IP\_OPTIONS}, contenente
- le opzioni IP del protocollo (vedi sez.~\ref{sec:IP_options}). Le
- intestazioni di instradamento e le altre opzioni sono già riempite con i
- dati locali. L'opzione richiede per \param{optval} un intero usato come
- valore logico. L'opzione non è supportata per socket di tipo
- \const{SOCK\_STREAM}.
-
\item[\constd{IP\_RETOPTS}] Identica alla precedente \const{IP\_RECVOPTS}, ma
in questo caso restituisce i dati grezzi delle opzioni, senza che siano
riempiti i capi di instradamento e le marche temporali. L'opzione richiede
per \param{optval} un intero usato come valore logico. L'opzione non è
supportata per socket di tipo \const{SOCK\_STREAM}.
+\item[\constd{IP\_ROUTER\_ALERT}] Questa è una opzione introdotta con i
+ kernel della serie 2.2.x, ed è specifica di Linux. Prende per
+ \param{optval} un intero usato come valore logico. Se abilitata
+ passa tutti i pacchetti con l'opzione \textit{IP Router Alert} (vedi
+ sez.~\ref{sec:IP_options}) che devono essere inoltrati al socket
+ corrente. Può essere usata soltanto per socket di tipo raw.
+
\item[\constd{IP\_TOS}] L'opzione consente di leggere o impostare il campo
\textit{Type of Service} dell'intestazione IP (per una trattazione più
dettagliata, che riporta anche i valori possibili e le relative costanti di
definizione si veda sez.~\ref{sec:IP_header}) che permette di indicare le
priorità dei pacchetti. Se impostato il valore verrà mantenuto per tutti i
pacchetti del socket; alcuni valori (quelli che aumentano la priorità)
- richiedono i privilegi di amministrazione con la capability
+ richiedono i privilegi di amministrazione con la \textit{capability}
\const{CAP\_NET\_ADMIN}.
Il campo TOS è di 8 bit e l'opzione richiede per \param{optval} un intero
estesa si veda sez.~\ref{sec:IP_header}). Il campo TTL è di 8 bit e
l'opzione richiede che \param{optval} sia un intero, che ne conterrà il
valore.
-
-\item[\constd{IP\_MINTTL}] L'opzione, introdotta con il kernel 2.6.34, imposta
- un valore minimo per il campo \textit{Time to Live} dei pacchetti associati
- al socket su cui è attivata, che se non rispettato ne causa lo scarto
- automatico. L'opzione è nata per implementare
- l'\href{http://www.ietf.org/rfc/rfc5082.txt}{RFC~5082} che la prevede come
- forma di protezione per i router che usano il protocollo BGP poiché questi,
- essendo in genere adiacenti, possono, impostando un valore di 255, scartare
- automaticamente tutti gli eventuali pacchetti falsi creati da un attacco a
- questo protocollo, senza doversi curare di verificarne la
- validità.\footnote{l'attacco viene in genere portato per causare un
- \textit{Denial of Service} aumentando il consumo di CPU del router nella
- verifica dell'autenticità di un gran numero di pacchetti di pacchetti
- falsi; questi, arrivando da sorgenti diverse da un router adiacente, non
- potrebbero più avere un TTL di 255 anche qualora questo fosse stato il
- valore di partenza, e l'impostazione dell'opzione consente di scartarli
- senza carico aggiuntivo sulla CPU (che altrimenti dovrebbe calcolare una
- checksum).}
-
-\item[\constd{IP\_HDRINCL}] Se abilitata l'utente deve fornire lui stesso
- l'intestazione IP in cima ai propri dati. L'opzione è valida soltanto per
- socket di tipo \const{SOCK\_RAW}, e quando utilizzata eventuali valori
- impostati con \const{IP\_OPTIONS}, \const{IP\_TOS} o \const{IP\_TTL} sono
- ignorati. In ogni caso prima della spedizione alcuni campi
- dell'intestazione vengono comunque modificati dal kernel, torneremo
- sull'argomento in sez.~\ref{sec:socket_raw}
-
-\item[\constd{IP\_RECVERR}] Questa è una opzione introdotta con i kernel della
- serie 2.2.x, ed è specifica di Linux. Essa permette di usufruire di un
- meccanismo affidabile per ottenere un maggior numero di informazioni in caso
- di errori. Se l'opzione è abilitata tutti gli errori generati su un socket
- vengono memorizzati su una coda, dalla quale poi possono essere letti con
- \func{recvmsg} (vedi sez.~\ref{sec:net_sendmsg}) come messaggi ancillari
- (torneremo su questo in sez.~\ref{sec:net_ancillary_data}) di tipo
- \const{IP\_RECVERR}. L'opzione richiede per \param{optval} un intero usato
- come valore logico e non è applicabile a socket di tipo
- \const{SOCK\_STREAM}.
-
-\itindbeg{Path~MTU}
-\item[\constd{IP\_MTU\_DISCOVER}] Questa è una opzione introdotta con i kernel
- della serie 2.2.x, ed è specifica di Linux. L'opzione permette di scrivere
- o leggere le impostazioni della modalità usata per la determinazione della
- \textit{Path MTU} (vedi sez.~\ref{sec:net_lim_dim}) del
- socket. L'opzione prende per \param{optval} un valore intero che indica la
- modalità usata, da specificare con una delle costanti riportate in
- tab.~\ref{tab:sock_ip_mtu_discover}.
-
- \begin{table}[!htb]
- \centering
- \footnotesize
- \begin{tabular}[c]{|l|r|p{7cm}|}
- \hline
- \multicolumn{2}{|c|}{\textbf{Valore}}&\textbf{Significato} \\
- \hline
- \hline
- \constd{IP\_PMTUDISC\_DONT}&0& Non effettua la ricerca dalla \textit{Path
- MTU}.\\
- \constd{IP\_PMTUDISC\_WANT}&1& Utilizza il valore impostato per la rotta
- utilizzata dai pacchetti (dal comando
- \texttt{route}).\\
- \constd{IP\_PMTUDISC\_DO} &2& Esegue la procedura di determinazione
- della \textit{Path MTU} come richiesto
- dall'\href{http://www.ietf.org/rfc/rfc1191.txt}{RFC~1191}.\\
- \hline
- \end{tabular}
- \caption{Valori possibili per l'argomento \param{optval} di
- \const{IP\_MTU\_DISCOVER}.}
- \label{tab:sock_ip_mtu_discover}
- \end{table}
-
- Il valore di default applicato ai socket di tipo \const{SOCK\_STREAM} è
- determinato dal parametro \texttt{ip\_no\_pmtu\_disc} (vedi
- sez.~\ref{sec:sock_sysctl}), mentre per tutti gli altri socket di default la
- ricerca è disabilitata ed è responsabilità del programma creare pacchetti di
- dimensioni appropriate e ritrasmettere eventuali pacchetti persi. Se
- l'opzione viene abilitata, il kernel si incaricherà di tenere traccia
- automaticamente della \textit{Path MTU} verso ciascuna destinazione, e
- rifiuterà immediatamente la trasmissione di pacchetti di dimensioni maggiori
- della MTU con un errore di \errval{EMSGSIZE}.\footnote{in caso contrario la
- trasmissione del pacchetto sarebbe effettuata, ottenendo o un fallimento
- successivo della trasmissione, o la frammentazione dello stesso.}
-
-\item[\constd{IP\_MTU}] Permette di leggere il valore della \textit{Path MTU}
- di percorso del socket. L'opzione richiede per \param{optval} un intero che
- conterrà il valore della \textit{Path MTU} in byte. Questa è una opzione
- introdotta con i kernel della serie 2.2.x, ed è specifica di Linux.
-
- È tramite questa opzione che un programma può leggere, quando si è avuto un
- errore di \errval{EMSGSIZE}, il valore della MTU corrente del socket. Si
- tenga presente che per poter usare questa opzione, oltre ad avere abilitato
- la scoperta della \textit{Path MTU}, occorre che il socket sia stato
- esplicitamente connesso con \func{connect}.
-
- Ad esempio con i socket UDP si potrà ottenere una stima iniziale della
- \textit{Path MTU} eseguendo prima una \func{connect} verso la destinazione,
- e poi usando \func{getsockopt} con questa opzione. Si può anche avviare
- esplicitamente il procedimento di scoperta inviando un pacchetto di grosse
- dimensioni (che verrà scartato) e ripetendo l'invio coi dati aggiornati. Si
- tenga infine conto che durante il procedimento i pacchetti iniziali possono
- essere perduti, ed è compito dell'applicazione gestirne una eventuale
- ritrasmissione.
-
-\itindend{Path~MTU}
-
-\item[\constd{IP\_ROUTER\_ALERT}] Questa è una opzione introdotta con i
- kernel della serie 2.2.x, ed è specifica di Linux. Prende per
- \param{optval} un intero usato come valore logico. Se abilitata
- passa tutti i pacchetti con l'opzione \textit{IP Router Alert} (vedi
- sez.~\ref{sec:IP_options}) che devono essere inoltrati al socket
- corrente. Può essere usata soltanto per socket di tipo raw.
-
-\item[\constd{IP\_MULTICAST\_TTL}] L'opzione permette di impostare o leggere il
- valore del campo TTL per i pacchetti \textit{multicast} in uscita associati
- al socket. È importante che questo valore sia il più basso possibile, ed il
- default è 1, che significa che i pacchetti non potranno uscire dalla rete
- locale. Questa opzione consente ai programmi che lo richiedono di superare
- questo limite. L'opzione richiede per
- \param{optval} un intero che conterrà il valore del TTL.
-
-\item[\constd{IP\_MULTICAST\_LOOP}] L'opzione consente di decidere se i dati
- che si inviano su un socket usato con il \textit{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 in locale l'uso di questa opzione permette di disabilitare
- questo tipo di traffico.
-
-\item[\constd{IP\_ADD\_MEMBERSHIP}] L'opzione consente di unirsi ad gruppo di
- \textit{multicast}, e può essere usata solo con \func{setsockopt}.
- L'argomento \param{optval} in questo caso deve essere una struttura di tipo
- \struct{ip\_mreqn}, illustrata in fig.~\ref{fig:ip_mreqn_struct}, che
- permette di indicare, con il campo \var{imr\_multiaddr} l'indirizzo del
- gruppo di \textit{multicast} a cui ci si vuole unire, con il campo
- \var{imr\_address} l'indirizzo dell'interfaccia locale con cui unirsi al
- gruppo di \textit{multicast} e con \var{imr\_ifindex} l'indice
- dell'interfaccia da utilizzare (un valore nullo indica una interfaccia
- qualunque).
-
- Per compatibilità è possibile utilizzare anche un argomento di tipo
- \struct{ip\_mreq}, una precedente versione di \struct{ip\_mreqn}, che
- differisce da essa soltanto per l'assenza del campo \var{imr\_ifindex}.
-
-\begin{figure}[!htb]
- \footnotesize \centering
- \begin{minipage}[c]{0.80\textwidth}
- \includestruct{listati/ip_mreqn.h}
- \end{minipage}
- \caption{La struttura \structd{ip\_mreqn} utilizzata dalle opzioni dei
- socket per le operazioni concernenti l'appartenenza ai gruppi di
- \textit{multicast}.}
- \label{fig:ip_mreqn_struct}
-\end{figure}
-
-\item[\constd{IP\_DROP\_MEMBERSHIP}] Lascia un gruppo di \textit{multicast},
- prende per \param{optval} la stessa struttura \struct{ip\_mreqn} (o
- \struct{ip\_mreq}) usata anche per \const{IP\_ADD\_MEMBERSHIP}.
-
-\item[\constd{IP\_MULTICAST\_IF}] Imposta l'interfaccia locale per l'utilizzo
- del \textit{multicast}, ed utilizza come \param{optval} le stesse strutture
- \struct{ip\_mreqn} o \struct{ip\_mreq} delle due precedenti opzioni.
-
-% TODO chiarire quale è la struttura \struct{ip\_mreq}
-
-
\end{basedescript}
\item[\constd{TCP\_INFO}] questa opzione, specifica di Linux, ma introdotta
anche in altri kernel (ad esempio FreeBSD) permette di controllare lo stato
- interno di un socket TCP direttamente da un programma in user space.
+ interno di un socket TCP direttamente da un programma in \textit{user space}.
L'opzione restituisce in una speciale struttura \struct{tcp\_info}, la cui
definizione è riportata in fig.~\ref{fig:tcp_info_struct}, tutta una serie
di dati che il kernel mantiene, relativi al socket. Anche questa opzione
situazione.} utilizzare per il singolo socket. L'opzione è stata
introdotta con il kernel 2.6.13,\footnote{alla data di stesura di queste
note (Set. 2006) è pure scarsamente documentata, tanto che non è neanche
- definita nelle intestazioni delle \acr{glibc} per cui occorre definirla a
+ definita nelle intestazioni della \acr{glibc} per cui occorre definirla a
mano al suo valore che è 13.} e prende come per \param{optval} il
puntatore ad un buffer contenente il nome dell'algoritmo di controllo che
si vuole usare.
Trip Time} cui abbiamo già accennato in sez.~\ref{sec:net_tcp}.} dei
pacchetti sulla rete.
-\item[\constd{SIOCSPGRP}] imposta il processo o il \textit{process group} a cui
- inviare i segnali \signal{SIGIO} e \signal{SIGURG} quando viene completata
- una operazione di I/O asincrono o arrivano dei dati urgenti
+\item[\constd{SIOCSPGRP}] imposta il processo o il \textit{process group} a
+ cui inviare i segnali \signal{SIGIO} e \signal{SIGURG} quando viene
+ completata una operazione di I/O asincrono o arrivano dei dati urgenti
(\texttt{out-of-band}). Il terzo argomento deve essere un puntatore ad una
variabile di tipo \type{pid\_t}; un valore positivo indica direttamente il
\ids{PID} del processo, mentre un valore negativo indica (col valore
assoluto) il \textit{process group}. Senza privilegi di amministratore o la
- capability \const{CAP\_KILL} si può impostare solo se stessi o il proprio
- \textit{process group}.
+ \textit{capability} \const{CAP\_KILL} si può impostare solo se stessi o il
+ proprio \textit{process group}.
\item[\constd{SIOCGPGRP}] legge le impostazioni presenti sul socket
relativamente all'eventuale processo o \textit{process group} cui devono
Il \textit{bucket filter} è un algoritmo generico che permette di impostare
dei limiti di flusso su una quantità\footnote{uno analogo viene usato per
- imporre dei limiti sul flusso dei pacchetti nel \itindex{netfilter}
- \textit{netfilter} di Linux (il \textit{netfilter} è l'infrastruttura
- usata per il filtraggio dei pacchetti del kernel, per maggiori dettagli si
- consulti il cap.~2 di \cite{FwGL}).} senza dovere eseguire medie
- temporali, che verrebbero a dipendere in misura non controllabile dalla
- dimensione dell'intervallo su cui si media e dalla distribuzione degli
- eventi;\footnote{in caso di un picco di flusso (il cosiddetto
- \textit{burst}) il flusso medio verrebbe a dipendere in maniera esclusiva
- dalla dimensione dell'intervallo di tempo su cui calcola la media.} in
- questo caso si definisce la dimensione di un ``\textsl{bidone}'' (il
- \textit{bucket}) e del flusso che da esso può uscire, la presenza di una
- dimensione iniziale consente di assorbire eventuali picchi di emissione,
- l'aver fissato un flusso di uscita garantisce che a regime questo sarà il
- valore medio del flusso ottenibile dal \textit{bucket}.
+ imporre dei limiti sul flusso dei pacchetti nel \textit{netfilter} di
+ Linux.} senza dovere eseguire medie temporali, che verrebbero a dipendere
+ in misura non controllabile dalla dimensione dell'intervallo su cui si media
+ e dalla distribuzione degli eventi;\footnote{in caso di un picco di flusso
+ (il cosiddetto \textit{burst}) il flusso medio verrebbe a dipendere in
+ maniera esclusiva dalla dimensione dell'intervallo di tempo su cui calcola
+ la media.} in questo caso si definisce la dimensione di un
+ ``\textsl{bidone}'' (il \textit{bucket}) e del flusso che da esso può
+ uscire, la presenza di una dimensione iniziale consente di assorbire
+ eventuali picchi di emissione, l'aver fissato un flusso di uscita garantisce
+ che a regime questo sarà il valore medio del flusso ottenibile dal
+ \textit{bucket}.
\itindend{bucket~filter}
dati ancillari e di controllo (vedi sez.~\ref{sec:net_ancillary_data}).
\end{basedescript}
-Oltre a questi nella directory \texttt{/proc/sys/net/core} si trovano altri
-file, la cui documentazione dovrebbe essere mantenuta nei sorgenti del kernel,
-nel file \texttt{Documentation/networking/ip-sysctl.txt}; la maggior parte di
-questi però non è documentato:
+Oltre a questi, nella directory \texttt{/proc/sys/net/core} si trovano diversi
+altri file, la cui documentazione, come per gli altri, dovrebbe essere
+mantenuta nei sorgenti del kernel nel file
+\texttt{Documentation/networking/ip-sysctl.txt}; la maggior parte di questi
+però non è documentato:
\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
\item[\sysctlrelfiled{net/core}{dev\_weight}] blocco di lavoro (\textit{work
quantum}) dello \textit{scheduler} di processo dei pacchetti.
disabilitare globalmente il procedimento con questo parametro ha pesanti
ripercussioni in termini di prestazioni di rete.
-\item[\sysctlrelfiled{net/ipv4}{ip\_always\_defrag}] fa si che tutti i
+\item[\sysctlrelfiled{net/ipv4}{ip\_always\_defrag}] fa sì che tutti i
pacchetti IP frammentati siano riassemblati, anche in caso in successivo
immediato inoltro.\footnote{introdotto con il kernel 2.2.13, nelle versioni
precedenti questo comportamento poteva essere solo stabilito un volta per
\item[\sysctlrelfiled{net/ipv4}{ipfrag\_high\_thresh}] indica il limite
massimo (espresso in numero di byte) sui pacchetti IP frammentati presenti
- in coda; quando questo valore viene raggiunta la coda viene ripulita fino al
+ in coda; quando questo valore viene raggiunto la coda viene ripulita fino al
valore \texttt{ipfrag\_low\_thresh}. Prende un valore intero.
-\item[\sysctlrelfiled{net/ipv4}{ipfrag\_low\_thresh}] soglia bassa
- (specificata in byte) a cui viene riportata la coda dei pacchetti IP
- frammentati quando si raggiunge il valore massimo dato da
+\item[\sysctlrelfiled{net/ipv4}{ipfrag\_low\_thresh}] indica la dimensione
+ (specificata in byte) della soglia inferiore a cui viene riportata la coda
+ dei pacchetti IP frammentati quando si raggiunge il valore massimo dato da
\texttt{ipfrag\_high\_thresh}. Prende un valore intero.
\item[\sysctlrelfiled{net/ipv4}{ip\_nonlocal\_bind}] se abilitato rende
possibile ad una applicazione eseguire \func{bind} anche su un indirizzo che
non è presente su nessuna interfaccia locale. Prende un valore logico e di
- default è disabilitato.
+ default è disabilitato. La funzionalità può essere abilitata a livello di
+ singolo socket con l'opzione \const{IP\_FREEBIND} illustrata in
+ sez.~\ref{sec:sock_ipv4_options}.
Questo può risultare utile per applicazioni particolari (come gli
\textit{sniffer}) che hanno la necessità di ricevere pacchetti anche non
\item[\sysctlrelfiled{net/ipv4}{tcp\_app\_win}] indica la frazione della
finestra TCP che viene riservata per gestire l'overhaed dovuto alla
- bufferizzazione. Prende un valore valore intero che consente di calcolare la
+ bufferizzazione. Prende un valore intero che consente di calcolare la
dimensione in byte come il massimo fra la MSS e
$\texttt{window}/2^\texttt{tcp\_app\_win}$. Un valore nullo significa che
non viene riservato nessuno spazio; il valore di default è 31.
\item[\sysctlrelfiled{net/ipv4}{tcp\_ecn}] abilita il meccanismo della
\textit{Explicit Congestion Notification} (in breve ECN) nelle connessioni
TCP. Prende valore logico che di default è disabilitato. La \textit{Explicit
- Congestion Notification} \itindex{Explicit~Congestion~Notification} è un
- meccanismo che consente di notificare quando una rotta o una rete è
+ Congestion Notification} \itindex{Explicit~Congestion~Notification~(ECN)}
+ è un meccanismo che consente di notificare quando una rotta o una rete è
congestionata da un eccesso di traffico,\footnote{il meccanismo è descritto
in dettaglio nell'\href{http://www.ietf.org/rfc/rfc3168.txt}{RFC~3168}
mentre gli effetti sulle prestazioni del suo utilizzo sono documentate
risposta prima che il kernel decida che la connessione è caduta e la
termini. Prende un valore intero che di default è 9.
-\item[\sysctlrelfiled{net/ipv4}{tcp\_keepalive\_time}] indica il numero
- di secondi che devono passare senza traffico sulla connessione prima che il
- kernel inizi ad inviare pacchetti di pacchetti di
- \textit{keepalive}.\footnote{ha effetto solo per i socket per cui si è
- impostata l'opzione \const{SO\_KEEPALIVE} (vedi
- sez.~\ref{sec:sock_options_main}.} Prende un valore intero che di default
- è 7200, pari a due ore.
+\item[\sysctlrelfiled{net/ipv4}{tcp\_keepalive\_time}] indica il numero di
+ secondi che devono passare senza traffico sulla connessione prima che il
+ kernel inizi ad inviare pacchetti di \textit{keepalive}.\footnote{ha effetto
+ solo per i socket per cui si è impostata l'opzione \const{SO\_KEEPALIVE}
+ (vedi sez.~\ref{sec:sock_options_main}.} Prende un valore intero che di
+ default è 7200, pari a due ore.
\item[\sysctlrelfiled{net/ipv4}{tcp\_low\_latency}] indica allo stack
TCP del kernel di ottimizzare il comportamento per ottenere tempi di latenza
\item[\sysctlrelfiled{net/ipv4}{tcp\_tw\_recycle}] abilita il riutilizzo
rapido dei socket in stato \texttt{TIME\_WAIT}. Prende un valore logico e di
default è disabilitato. Non è opportuno abilitare questa opzione che può
- causare problemi con il NAT.\footnote{il
- \itindex{Network~Address~Translation} \textit{Network Address Translation}
- è una tecnica, impiegata nei firewall e nei router, che consente di
- modificare al volo gli indirizzi dei pacchetti che transitano per una
- macchina, Linux la supporta con il \textit{netfilter}.}
+ causare problemi con il NAT.\footnote{la
+ \itindex{Network~Address~Translation~(NAT)} \textit{Network Address
+ Translation} (abbreviato in NAT) è una tecnica, impiegata nei firewall e
+ nei router, che consente di modificare al volo gli indirizzi dei pacchetti
+ che transitano per una macchina, Linux la supporta con il
+ \textit{netfilter}.}
\item[\sysctlrelfiled{net/ipv4}{tcp\_tw\_reuse}] abilita il riutilizzo
dello stato \texttt{TIME\_WAIT} quando questo è sicuro dal punto di vista
\item il secondo valore, denominato \textit{default}, indica la dimensione
di default in byte del buffer di spedizione di un socket TCP. Questo
valore sovrascrive il default iniziale impostato per tutti i tipi di
- socket con \sysctlfile{net/core/wmem\_default}. Il default è 87380 byte,
- ridotto a 43689 per sistemi con poca memoria. Si può aumentare questo
- valore quando si desiderano dimensioni più ampie del buffer di
+ socket sul file \sysctlfile{net/core/wmem\_default}. Il default è 87380
+ byte, ridotto a 43689 per sistemi con poca memoria. Si può aumentare
+ questo valore quando si desiderano dimensioni più ampie del buffer di
trasmissione per i socket TCP, ma come per il precedente
\sysctlrelfile{net/ipv4}{tcp\_rmem}) se si vuole che in corrispondenza
aumentino anche le dimensioni usate per la finestra TCP si deve abilitare