\var{getipnodebyaddr} ed è stata introdotta una interfaccia completamente
nuova.
-La prima funzione di questa interfaccia, che combina le funzionalità di
-\func{getipnodebyname}, \func{getipnodebyaddr}, \func{getservbyname} e
-\func{getservbyport}, consentendo di ottenere contemporaneamente la
-risoluzione di un indirizzo e di un servizio, è \funcd{getaddrinfo}, il cui
-prototipo è:
+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
+un servizio; il suo prototipo è:
\begin{functions}
\headdecl{netdb.h}
\headdecl{sys/socket.h}
\end{functions}
La funzione prende come primo argomento il nome della macchina che si vuole
-risolvere. Questo, oltre ad un comune nome a dominio, può essere anche un
-indirizzo numerico in forma \textit{dotted-decimal} per IPv4 o in formato
-esadecimale per IPv6. Si può anche specificare il nome di una rete invece che
-di una singola macchina. Il secondo argomento specifica invece il nome del
-servizio che si intende risolvere. Uno di questi due argomenti può essere
-anche inizializzato a \const{NULL}
+risolvere, specificato tramite la stringa \param{node}. Questo argomento,
+oltre ad un comune nome a dominio, può indicare anche un indirizzo numerico in
+forma \textit{dotted-decimal} per IPv4 o in formato esadecimale per IPv6. Si
+può anche specificare il nome di una rete invece che di una singola macchina.
+Il secondo argomento, \param{service}, specifica invece il nome del servizio
+che si intende risolvere. Per uno dei due argomenti si può anche usare il
+valore \const{NULL}, nel qual caso la risoluzione verrà effettuata utilizzando
+soltantoo sulla base del valore dell'altro.
+
+Il terzo argomento, \param{hints}, deve essere invece un puntatore ad una
+struttura \struct{addrinfo} usata per dare dei \textsl{suggerimenti} al
+procedimento di risoluzione riguardo al protocollo o del tipo di socket che si
+intenderà utilizzare; la funzione infatti permette di effettuare ricerche
+generiche sugli indirizzi, usando sia IPv4 che IPv6, e richiedere risoluzioni
+sui nomi dei servizi indipendentemente dal protocollo (ad esempio TCP o UDP)
+che questi possono utilizzare.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \includestruct{listati/addrinfo.h}
+ \end{minipage}
+ \caption{La struttura \structd{addrinfo} usata nella nuova interfaccia POSIX
+ per la risoluzione di nomi a dominio e servizi.}
+ \label{fig:sock_addrinfo_struct}
+\end{figure}
+
+La struttura \struct{addrinfo}, la cui definizione\footnote{la definizione è
+ ripresa direttamente dal file \texttt{netdb.h} in 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.} è riportata 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. Il primo campo, \var{ai\_flags}, è una maschera binaria di bit che
+permettono di controllare le varie modalità di risoluzione degli indirizzi,
+che viene usato soltanto in ingresso. I tre campi successivi \var{ai\_family},
+\var{ai\_socktype}, e \var{ai\_protocol} contengono rispettivamente la
+famiglia di indirizzi, il tipo di socket e il protocollo, in ingresso vengono
+usati per impostare una selezione (impostandone il valore nella struttura
+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} è il puntatore alla stringa contenente il nome
+canonico della macchina, ed infine, quando la funzione restituisce più di un
+risultato, \var{ai\_next} è il puntatore alla struttura \struct{addrinfo}
+successiva della lista.
+
+Ovviamente non è necessario dare dei suggerimenti in ingresso, ed usando
+\const{NULL} come valore per l'argomento \param{hints} si possono compiere
+ricerche generiche. Se però si specifica un valore non nullo questo deve
+puntare ad una struttura \struct{addrinfo} precedentemente allocata nella
+quale siano stati opportunamente impostati i valori dei campi
+\var{ai\_family}, \var{ai\_socktype}, \var{ai\_protocol} ed \var{ai\_flags}.
+
+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
+se non si vuole specificare questo nessuna famiglia di indirizzi si può usare
+il valore \const{PF\_UNSPEC}. Allo stesso modo per \var{ai\_socktype} si
+possono usare i valori illustrati 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,
+se non si vuole effettuare nessuna risoluzione specifica, si potrà usare un
+valore nullo.
+
+Il campo \var{ai\_protocol} permette invece di effettuare la selezione dei
+risultati per il nome del servizio usando il numero identificativo del
+rispettivo protocollo di trasporto (i cui valori possibili sono riportati in
+\file{/etc/protocols}); di nuovo i due soli valori utilizzabili sono quelli
+relativi a UDP e TCP, o il valore nullo che indica di ignorare questo campo
+nella selezione.
+
+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.
+
+\begin{table}[!htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{10cm}|}
+ \hline
+ \textbf{Costante} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{AI\_PASSIVE} & viene utilizzato per ottenere un indirizzo in
+ formato adatto per una successiva chiamata a
+ \func{bind}. Se specificato quando si è usato
+ \const{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 verrano restituiti in formato adatto ad
+ una chiamata a \func{connect} o \func{sendto}.\\
+ \const{AI\_CANONNAME} & richiede la restituzione del nome canonico della
+ macchina, che verrà salvato in una stringa il cui
+ indirizzo sarà restituito nel campo
+ \var{ai\_canonname} della prima struttura
+ \struct{addrinfo} dei risultati. Se il nome
+ canonico non è disponibile al suo posto
+ viene restituita una copia di \param{node}. \\
+ \const{AI\_NUMERICHOST}& se impostato il nome della macchina specificato
+ con \param{node} deve essere espresso in forma
+ numerica, altrimenti sarà restituito un errore
+ \const{EAI\_NONAME} (vedi
+ tab.~\ref{tab:addrinfo_error_code}), in questo
+ modo si evita ogni chiamata alle funzioni di
+ risoluzione.\\
+ \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}.\\
+ \hline
+ \end{tabular}
+ \caption{Costanti associate ai bit del campo \var{ai\_flags} della struttura
+ \struct{addrinfo}.}
+ \label{tab:ai_flags_values}
+\end{table}
+
+Come ultimo argomento di \func{getaddrinfo} deve essere passato un puntatore
+ad una variabile (di tipo puntatore ad una struttura \struct{addrinfo}) che
+verrà utilizzata dalla funzione per restituire (come \textit{value result
+ argument}) i propri risultati. La funzione infatti è rientrante, ed alloca
+autonomamente tutta la memoria necessaria in cui verranno riportati i
+risultati della risoluzione. La funzione restituisce in \param{res} il
+puntatore alla prima di una \textit{linked list} di strutture di tipo
+\struct{addrinfo} contenenti tutte le informazioni ottenute.
+
+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
+tab.~\ref{tab:addrinfo_error_code}; dato che la funzione utilizza altre
+funzioni e chiamate al sistema per ottenere il suo risultato in generale il
+valore di \var{errno} non è significativo, eccetto il caso in cui si sia
+ricevuto un errore di \const{EAI\_SYSTEM}, nel qual caso l'errore
+corrispondente è riportato tramite \var{errno}.
+
+\begin{table}[!htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{10cm}|}
+ \hline
+ \textbf{Costante} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{EAI\_FAMILY} & la famiglia di indirizzi richiesta non è
+ supportata. \\
+ \const{EAI\_SOCKTYPE}& il tipo di socket richiesto non è supportato. \\
+ \const{EAI\_BADFLAGS}& il campo \var{ai\_flags} contiene dei valori non
+ validi. \\
+ \const{EAI\_NONAME} & il nome a dominio o il servizio non sono noti,
+ viene usato questo errore anche quando si specifica
+ il valore \const{NULL} per entrambi gli argomenti
+ \param{node} e \param{service}. \\
+ \const{EAI\_SERVICE} & il servizio richiesto non è disponibile per il tipo
+ di socket richiesto, anche se può esistere per
+ altri tipi di socket. \\
+ \const{EAI\_ADDRFAMILY}& la rete richiesta non ha nessun indirizzo di rete
+ per la famiglia di indirizzi specificata. \\
+ \const{EAI\_NODATA} & la . \\
+ \const{EAI\_MEMORY} & è stato impossibile allocare la memoria necessaria
+ alle operazioni. \\
+ \const{EAI\_FAIL} & il DNS ha restituito un errore di risoluzione
+ permanente. \\
+ \const{EAI\_AGAIN} & il DNS ha restituito un errore di risoluzione
+ temporaneo, si può ritentare in seguito. \\
+ \const{EAI\_SYSTEM} & c'è stato un errore di sistema, si può controllare
+ \var{errno} per i dettagli. \\
+% \hline
+% estensioni GNU, trovarne la documentazione
+% \const{EAI\_INPROGRESS}& richiesta in corso. \\
+% \const{EAI\_CANCELED}& la richiesta è stata cancellata.\\
+% \const{EAI\_NOTCANCELED}& la richiesta non è stata cancellata. \\
+% \const{EAI\_ALLDONE} & tutte le richieste sono complete. \\
+% \const{EAI\_INTR} & richiesta interrotta. \\
+ \hline
+ \end{tabular}
+ \caption{Costanti associate ai valori dei codici di errore della funzione
+ \func{getaddrinfo}.}
+ \label{tab:addrinfo_error_code}
+\end{table}
+
+
+Dato che più di un indirizzo possono corrispondere ad un certo nome a dominio,
+e più di un servizio possono essere associati ad un certo nome (in genere su
+due protocolli diversi) è assolutamente normale ricevere come risposta una
+lista di più strutture \struct{addrinfo}, a meno di non avere usato una
+selezione specifica. Ad esempio se si richiede la risoluzione del servizio
+\textit{echo} si avrà come risposta la lista illustrata in
+fig.~\ref{fig:sock_addrinfo_list}.
+
+\begin{figure}[!htb]
+ \centering
+ \includegraphics[width=10cm]{img/addrinfo_list}
+ \caption{La \textit{linked list} delle strutture \struct{addrinfo}
+ restituite da \func{getaddrinfo}.}
+ \label{fig:sock_addrinfo_list}
+\end{figure}
+
+
+Una volta estratti i risultati dalla \textit{linked list} puntata da
+\param{res} 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}.
+
+ \bodydesc{La funzione non restituisce nessun codice di errore.}
+\end{functions}
+
+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}.
+