X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=socket.tex;h=e20c38800ce3e087de70946678e1a2854d80be31;hp=4d19955bb8e73676d7ad7d6ddb3db02106145f04;hb=d99b4995b23505a9afde30adf3a716aa7a55f0e9;hpb=efd164169524125422cf9bb80ff70a0b037886a0 diff --git a/socket.tex b/socket.tex index 4d19955..e20c388 100644 --- a/socket.tex +++ b/socket.tex @@ -6,8 +6,8 @@ principali meccanismi di comunicazione fra programmi utilizzato in ambito unix (e non solo). Il socket costituisce in sostanza un canale di comunicazione fra due processi su cui si possono leggere e scrivere dati analogo a quello di una pipe ma a differenza di questa e degli altri meccanismi esaminati nel capitolo -\ref{cha:IPC} i socket non sono limitati alla comunicazione fra processi che -girano sulla stessa macchina ma possono effettuare la comunicazione anche +\capref{cha:IPC} i socket non sono limitati alla comunicazione fra processi +che girano sulla stessa macchina ma possono effettuare la comunicazione anche attraverso la rete. Quella dei socket costituisce infatti la principale API (\textit{Application @@ -29,8 +29,8 @@ tratteremo in maniera pi \label{sec:sock_gen} Per capire il funzionamento dei socket occorre avere presente il funzionamento -dei protocolli di rete (vedi \ref{cha:network}), ma l'interfaccia è del tutto -generale e benché le problematiche (e quindi le modalità di risolvere i +dei protocolli di rete (vedi \capref{cha:network}), ma l'interfaccia è del +tutto generale e benché le problematiche (e quindi le modalità di risolvere i problemi) siano diverse a seconda del tipo di protocollo di comunicazione usato, le funzioni da usare restano le stesse. @@ -75,21 +75,19 @@ dei file che contiene i puntatori alle opportune strutture usate dal kernel ed allocate per ogni processo, (la stessa usata per i files e le pipes [NdA verificare!]). -Il prototipo della funzione è definito nell'header \texttt{sys/socket.h}, la -funzione prende tre parametri, il dominio del socket (che definisce la -famiglia di protocolli, vedi \ref{sec:sock_domain}), il tipo di socket (che -definisce lo stile di comunicazione vedi \ref{sec:sock_type}) e il protocollo; -in genere quest'ultimo è indicato implicitamente dal tipo di socket, per cui -viene messo a zero (con l'eccezione dei \textit{raw socket}). +La funzione prende tre parametri, il dominio del socket (che definisce la +famiglia di protocolli, vedi \secref{sec:sock_domain}), il tipo di socket (che +definisce lo stile di comunicazione vedi \secref{sec:sock_type}) e il +protocollo; in genere quest'ultimo è indicato implicitamente dal tipo di +socket, per cui viene messo a zero (con l'eccezione dei \textit{raw socket}). -\begin{itemize} -\item \texttt{int socket(int domain, int type, int protocol)} +\begin{prototype}{sys/socket.h}{int socket(int domain, int type, int protocol)} La funzione restituisce un intero positivo se riesce, e -1 se fallisce, in quest'ultimo caso la variabile \texttt{errno} è settata con i seguenti codici di errore: - \begin{itemize} + \begin{errlist} \item \texttt{EPROTONOSUPPORT} Il tipo di socket o il protocollo scelto non sono supportati nel dominio. \item \texttt{ENFILE} Il kernel non ha memoria sufficiente a creare una @@ -100,8 +98,8 @@ viene messo a zero (con l'eccezione dei \textit{raw socket}). \item \texttt{EINVAL} Protocollo sconosciuto o dominio non disponibile. \item \texttt{ENOBUFS} o \texttt{ENOMEM} Non c'è sufficiente memoria per creare il socket. - \end{itemize} -\end{itemize} + \end{errlist} +\end{prototype} Si noti che la creazione del socket non comporta nulla riguardo all'indicazione degli indirizzi remoti o locali attraverso i quali si vuole @@ -119,7 +117,7 @@ altro nome con cui si indicano i domini. A ciascun tipo di dominio corrisponde un analogo nome simbolico che inizia per \texttt{AF\_} da \textit{address family}, e che identifica il formato degli -indirizzi usati in quel dominio; le man pages di linux si riferiscono a questi +indirizzi usati in quel dominio; le man pages di Linux si riferiscono a questi anche come \textit{name space}, (nome che però il manuale della glibc riserva ai domini) e che identifica il formato degli indirizzi usati in quel dominio. @@ -132,7 +130,7 @@ supportino diverse strutture di indirizzi, per cui nella pratica questi due nomi sono equivalenti e corrispondono agli stessi valori. I domini (e i relativi nomi simbolici), così come i nomi delle famiglie di -indirizzi sono definiti dall'header \textit{socket.h}. In linux le famiglie di +indirizzi sono definiti dall'header \textit{socket.h}. In Linux le famiglie di protocolli disponibili sono riportate in \ntab. \begin{table}[htb] @@ -152,13 +150,13 @@ protocolli disponibili sono riportate in \ntab. PF\_APPLETALK & Appletalk & ddp(7) \\ PF\_PACKET & Low level packet interface & packet(7) \\ \end{tabular} - \caption{Famiglie di protocolli definiti in linux} + \caption{Famiglie di protocolli definiti in Linux} \label{tab:net_pf_names} \end{table} Non tutte le famiglie di protocolli sono accessibili dall'utente generico, ad esempio in generale tutti i socket di tipo \texttt{SOCK\_RAW} possono essere -creati solo da processi che hanno i provilegi di root (cioè effective uid +creati solo da processi che hanno i privilegi di root (cioè effective uid uguale a zero) o la capability \texttt{CAP\_NET\_RAW}. @@ -168,7 +166,7 @@ uguale a zero) o la capability \texttt{CAP\_NET\_RAW}. La scelta di un dominio non comporta però la scelta dello stile di comunicazione, questo infatti viene a dipendere dal protocollo che si andrà ad utilizzare fra quelli disponibili nella famiglia scelta. Le API permettono di -scegliere lo stile di comunicazione indicando il tipo di socket; linux e le +scegliere lo stile di comunicazione indicando il tipo di socket; Linux e le glibc mettono a disposizione i seguenti tipi di socket (che il manuale della glibc chiama \textit{styles}) definiti come \texttt{int} in \texttt{socket.h}: @@ -270,7 +268,7 @@ in \nfig: \begin{figure}[!htbp] \footnotesize - \begin{lstlisting}{} + \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} struct sockaddr { sa_family_t sa_family; /* address family: AF_xxx */ char sa_data[14]; /* address (protocol-specific) */ @@ -286,7 +284,7 @@ invocano dette funzioni passando l'indirizzo di un protocollo specifico occorrerà eseguire un casting del relativo puntatore. I tipi di dati che compongono la struttura sono stabiliti dallo standard -Posix.1g, riassunti in \ntab\ con i rispettivi file di include in cui sono +POSIX.1g, riassunti in \ntab\ con i rispettivi file di include in cui sono definiti; la struttura è invece definita nell'include file \texttt{sys/socket.h} @@ -316,14 +314,14 @@ definiti; la struttura \hline \end{tabular} \caption{Tipi di dati usati nelle strutture degli indirizzi, secondo quanto - stabilito dallo standard Posix.1g} + stabilito dallo standard POSIX.1g} \label{tab:sock_data_types} \end{table} In alcuni sistemi la struttura è leggermente diversa e prevede un primo membro aggiuntivo \texttt{uint8\_t sin\_len} (come riportato da R. Stevens nei suoi libri). Questo campo non verrebbe usato direttamente dal programmatore e non è -richiesto dallo standard Posix.1g, in linux pertanto non sussiste. Il campo +richiesto dallo standard POSIX.1g, in Linux pertanto non sussiste. Il campo \texttt{sa\_family\_t} era storicamente un \texttt{unsigned short}. Dal punto di vista del programmatore l'unico uso di questa struttura è quello @@ -342,12 +340,12 @@ I socket di tipo \texttt{PF\_INET} vengono usati per la comunicazione attraverso internet; la struttura per gli indirizzi per un socket internet (IPv4) è definita come \texttt{sockaddr\_in} nell'header file \texttt{netinet/in.h} e secondo le man page ha la forma mostrata in \nfig, -conforme allo standard Posix.1g. +conforme allo standard POSIX.1g. \begin{figure}[!htbp] \footnotesize - \begin{lstlisting}{} + \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} struct sockaddr_in { sa_family_t sin_family; /* address family: AF_INET */ u_int16_t sin_port; /* port in network byte order */ @@ -371,35 +369,35 @@ RAW che accedono direttamente al livello di IP, nel qual caso il numero della porta viene settato al numero di protocollo. Il membro \texttt{sin\_family} deve essere sempre settato; \texttt{sin\_port} -specifica il numero di porta (vedi \ref{sec:TCPel_port_num}; i numeri di porta -sotto il 1024 sono chiamati \textsl{riservati} in quanto utilizzati da servizi -standard. Soltanto processi con i privilegi di root (effective uid uguale a -zero) o con la capability \texttt{CAP\_NET\_BIND\_SERVICE} possono usare la -funzione \texttt{bind} su queste porte. +specifica il numero di porta (vedi \secref{sec:TCPel_port_num}; i numeri di +porta sotto il 1024 sono chiamati \textsl{riservati} in quanto utilizzati da +servizi standard. Soltanto processi con i privilegi di root (effective uid +uguale a zero) o con la capability \texttt{CAP\_NET\_BIND\_SERVICE} possono +usare la funzione \texttt{bind} su queste porte. Il membro \texttt{sin\_addr} contiene l'indirizzo internet dell'altro capo della comunicazione, e viene acceduto sia come struttura (un resto di una -implementazione precedente in cui questa era una union usata per accedere alle +implementazione precedente in cui questa era una \texttt{union} usata per accedere alle diverse classi di indirizzi) che come intero. Infine è da sottolineare che sia gli indirizzi che i numeri di porta devono essere specificati in quello che viene chiamato \textit{network order}, cioè con i bit ordinati in formato \textit{big endian}, questo comporta la necessità di usare apposite funzioni di conversione per mantenere la -portabilità del codice (vedi \ref{sec:sock_addr_func} per i dettagli del +portabilità del codice (vedi \secref{sec:sock_addr_func} per i dettagli del problema e le relative soluzioni). \subsection{La struttura degli indirizzi IPv6} \label{sec:sock_sa_ipv6} -Essendo IPv6 una estenzione di IPv4 i socket di tipo \texttt{PF\_INET6} sono +Essendo IPv6 una estensione di IPv4 i socket di tipo \texttt{PF\_INET6} sono sostanzialmente identici ai precedenti; la parte in cui si trovano praticamente tutte le differenze è quella della struttura degli indirizzi. La struttura degli indirizzi è definita ancora in \texttt{netinet/in.h}. \begin{figure}[!htbp] \footnotesize - \begin{lstlisting}{} + \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} struct sockaddr_in6 { u_int16_t sin6_family; /* AF_INET6 */ u_int16_t sin6_port; /* port number */ @@ -419,11 +417,11 @@ struct in6_addr { Il campo \texttt{sin6\_family} deve essere sempre settato ad \texttt{AF\_INET6}, il campo \texttt{sin6\_port} è analogo a quello di IPv4 e -segue le stesse regole; il campo \texttt{sin6\_flowinfo} è a dua volta diviso +segue le stesse regole; il campo \texttt{sin6\_flowinfo} è a sua volta diviso in tre parti di cui i 24 bit inferiori indicano l'etichetta di flusso, i successivi 4 bit la priorità e gli ultimi 4 sono riservati; questi valori fanno riferimento ad alcuni campi specifici dell'header dei pacchetti IPv6 -(vedi \ref{sec:appA_ipv6}) ed il loro uso è sperimentale. +(vedi \secref{sec:IP_ipv6head}) ed il loro uso è sperimentale. Il campo \texttt{sin6\_addr} contiene l'indirizzo a 128 bit usato da IPv6, infine il campo \texttt{sin6\_scope\_id} è un campo introdotto con il kernel @@ -446,7 +444,7 @@ definita nel file di header \texttt{sys/un.h}. \begin{figure}[!htbp] \footnotesize - \begin{lstlisting}{} + \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} #define UNIX_PATH_MAX 108 struct sockaddr_un { sa_family_t sun_family; /* AF_UNIX */ @@ -500,7 +498,7 @@ utile anche in seguito. \subsection{La \textit{endianess}} \label{sec:sock_endianess} -La rappresentazione di un numbero binario in un computer può essere fatta in +La rappresentazione di un numero binario in un computer può essere fatta in due modi, chiamati rispettivamente \textit{big endian} e \textit{little endian} a seconda di come i singoli bit vengono aggregati per formare le variabili intere (in diretta corrispondenza a come sono poi in realtà cablati @@ -517,14 +515,16 @@ numero. Il caso opposto, in cui si parte dal bit meno significativo per lo stesso motivo \textit{big endian}. La \textit{endianess} di un computer dipende essenzialmente dalla architettura -hardware usata; intel e digital usano il little endian, motorola, ibm, sun +hardware usata; Intel e Digital usano il little endian, Motorola, IBM, Sun (sostanzialmente tutti gli altri) usano il big endian. Il formato della rete è -anch'esso big endian. Esistono poi anche dei processori che possono scegliere -il tipo di formato all'avvio e alcuni, come il PowerPC o l'intel i860, possono -pure passare da un tipo all'altro con una specifica istruzione; in ogni caso -in linux l'ordinamanento è definito dall'archiettura e anche se questi -cambiamenti sono possibili anche dopo che il sistema è avviato, non vengono -mai eseguiti. +anch'esso big endian, quello del bus PCI è little endian, quello del bus VME è +big endian. + +Esistono poi anche dei processori che possono scegliere il tipo di formato +all'avvio e alcuni, come il PowerPC o l'Intel i860, possono pure passare da un +tipo di ordinamento all'altro con una specifica istruzione; in ogni caso in +Linux l'ordinamento è definito dall'architettura e anche se questi cambiamenti +sono possibili anche dopo che il sistema è avviato, non vengono mai eseguiti. \subsection{Le funzioni per il riordinamento} \label{sec:sock_func_ord} @@ -533,34 +533,32 @@ Il problema connesso all'endianess di architettura all'altra i dati vengono interpretati in maniera diversa, e ad esempio nel caso dell'intero a 16 bit ci si ritroverà con i due bytes in cui è suddiviso scambiati di posto, e ne sarà quindi invertito l'ordine di lettura -per cui, per riavere il valore originale dovrenno essere rovesciati. +per cui, per riavere il valore originale dovranno essere rovesciati. -Per questo motivo si usano le seguenti funzioni di conversione (i cui -prototipi sono definiti in \texttt{netinet/in.h}) che servono a tener conto -automaticamente della possibile differenza fra l'ordinamento usato sul -computer e quello che viene usato nelle trasmissione sulla rete; queste +Per questo motivo si usano le seguenti funzioni di conversione che servono a +tener conto automaticamente della possibile differenza fra l'ordinamento usato +sul computer e quello che viene usato nelle trasmissione sulla rete; queste funzioni sono: -\begin{itemize} -\item \texttt{unsigned long int htonl(unsigned long int hostlong)} - +\begin{prototype}{netinet/in.h} +{unsigned long int htonl(unsigned long int hostlong)} Converte l'intero a 32 bit \texttt{hostlong} dal formato della macchina a quello della rete. - -\item \texttt{unsigned sort int htons(unsigned short int hostshort)} - +\end{prototype} +\begin{prototype}{netinet/in.h} +{unsigned short int htons(unsigned short int hostshort)} Converte l'intero a 16 bit \texttt{hostshort} dal formato della macchina a quello della rete. - -\item \texttt{unsigned long int ntonl(unsigned long int netlong)} - +\end{prototype} +\begin{prototype}{netinet/in.h} +{unsigned long int ntonl(unsigned long int netlong)} Converte l'intero a 32 bit \texttt{netlong} dal formato della rete a quello della macchina. - -\item \texttt{unsigned sort int ntons(unsigned short int netshort)} - +\end{prototype} +\begin{prototype}{netinet/in.h} +{unsigned sort int ntons(unsigned short int netshort)} Converte l'intero a 16 bit \texttt{netshort} dal formato della rete a quello della macchina. -\end{itemize} +\end{prototype} I nomi sono assegnati usando la lettera $n$ come mnemonico per indicare l'ordinamento usato sulla rete (da \textit{network order}) e la lettera $h$ come mnemonico per l'ordinamento usato sulla macchina locale (da \textit{host @@ -577,10 +575,9 @@ codice su tutte le architetture. \texttt{inet\_ntoa}} \label{sec:sock_func_ipv4} -Un secondo insieme di funzioni di manipolazione (i cui prototipi sono definiti -in \texttt{arpa/inet.h}) serve per passare dal formato binario usato nelle -strutture degli indirizzi alla rappresentazione dei numeri IP che si usa -normalente. +Un secondo insieme di funzioni di manipolazione serve per passare dal formato +binario usato nelle strutture degli indirizzi alla rappresentazione dei numeri +IP che si usa normalmente. Le prime tre funzioni di manipolazione riguardano la conversione degli indirizzi IPv4 da una stringa in cui il numero di IP è espresso secondo la @@ -588,32 +585,29 @@ cosiddetta notazione \textit{dotted-decimal}, (cio \texttt{192.160.0.1}) al formato binario (direttamente in \textit{network order}) e viceversa; in questo caso si usa la lettera $a$ come mnemonico per indicare la stringa. Dette funzioni sono: -\begin{itemize} -\item \texttt{int inet\_aton(const char *src, struct in\_addr *dest)} - - Converte la stringa puntata da \texttt{src} nell'indirizzo binario da - memorizzare all'indirizzo puntato da \texttt{dest}, restituendo 0 in caso - di successo e 1 in caso di fallimento (è espressa in questa forma in modo da - poterla usare direttamente con il puntatore usato per passare la struttura - degli indirizzi). Se usata con \texttt{dest} inizializzato a - \texttt{NULL} effettua la validazione dell'indirizzo. - -\item \texttt{in\_addr\_t inet\_addr(const char *strptr)} - +\begin{prototype}{arpa/inet.h} + {int inet\_aton(const char *src, struct in\_addr *dest)} Converte la stringa + puntata da \texttt{src} nell'indirizzo binario da memorizzare all'indirizzo + puntato da \texttt{dest}, restituendo 0 in caso di successo e 1 in caso di + fallimento (è espressa in questa forma in modo da poterla usare direttamente + con il puntatore usato per passare la struttura degli indirizzi). Se usata + con \texttt{dest} inizializzato a \texttt{NULL} effettua la validazione + dell'indirizzo. +\end{prototype} +\begin{prototype}{arpa/inet.h}{in\_addr\_t inet\_addr(const char *strptr)} Restituisce l'indirizzo a 32 bit in network order a partire dalla stringa passata come parametro, in caso di errore restituisce il valore \texttt{INADDR\_NONE} che tipicamente sono trentadue bit a uno; questo comporta che la stringa \texttt{255.255.255.255}, che pure è un indirizzo valido, non può essere usata con questa funzione; per questo motivo essa è generalmente deprecata in favore della precedente. - -\item \texttt{char *inet\_ntoa(struct in\_addr addrptr)} - +\end{prototype} +\begin{prototype}{arpa/inet.h}{char *inet\_ntoa(struct in\_addr addrptr)} Converte il valore a 32 bit dell'indirizzo (espresso in network order) restituendo il puntatore alla stringa che contiene l'espressione in formato dotted decimal. Si deve tenere presente che la stringa risiede in memoria statica, per cui questa funzione non è rientrante. -\end{itemize} +\end{prototype} \subsection{Le funzioni \texttt{inet\_pton} e \texttt{inet\_ntop}} @@ -621,50 +615,59 @@ indicare la stringa. Dette funzioni sono: Le tre funzioni precedenti sono limitate solo ad indirizzi IPv4, per questo motivo è preferibile usare le due nuove funzioni \texttt{inet\_pton} e -\texttt{inet\_ntop} che possono convertire anche gli indirizzi IPv6 (secondo -lo schema in \nfig). Anche in questo caso le lettere $n$ e $p$ sono degli -mnemonici per ricordare il tipo di conversione effettuata e stanno per -\textit{presentation} e \textit{numeric}. - -\begin{figure}[htb] - \centering - - \caption{Schema della rappresentazioni utilizzate dalle funzioni di - conversione \texttt{inet\_pton} e \texttt{inet\_ntop} } - \label{fig:sock_inet_conv_func} - -\end{figure} - -Entrambe le funzioni accettano l'argomento \texttt{family} che indica il tipo -di indirizzo e può essere \texttt{AF\_INET} o \texttt{AF\_INET6}. Se la -famiglia indicata non è valida entrambe le funzioni ritornano un valore -negativo e settano la variabile \texttt{errno} al valore -\texttt{EAFNOSUPPORT}. I prototipi delle suddette funzioni sono i seguenti: -\begin{itemize} -\item \texttt{int inet\_pton(int family, const char *src, void *dest)} - - Converte la stringa puntata da \texttt{src} nell'indirizzo binario da - memorizzare all'indirizzo puntato da \texttt{dest}, restituendo 0 in caso di - successo e 1 in caso di fallimento. - -\item \texttt{char *inet\_ntop(int family, const void *src, char *dest, - size\_t len)} - - Converte la struttura dell'indirizzo puntata da \texttt{src} in una stringa - che viene copiata nel buffer puntato dall'indirizzo \texttt{dest}; questo - deve essere preallocato dall'utente e la lunghezza deve essere almeno +\texttt{inet\_ntop} che possono convertire anche gli indirizzi IPv6. Anche in +questo caso le lettere $n$ e $p$ sono degli mnemonici per ricordare il tipo di +conversione effettuata e stanno per \textit{presentation} e \textit{numeric}. + +% \begin{figure}[htb] +% \centering + +% \caption{Schema della rappresentazioni utilizzate dalle funzioni di +% conversione \texttt{inet\_pton} e \texttt{inet\_ntop} } +% \label{fig:sock_inet_conv_func} + +% \end{figure} + +Entrambe le funzioni accettano l'argomento \texttt{af} che indica il tipo di +indirizzo e può essere \texttt{AF\_INET} o \texttt{AF\_INET6}. Se la famiglia +indicata non è valida entrambe le funzioni settano la variabile \texttt{errno} +al valore \texttt{EAFNOSUPPORT}. I prototipi delle suddette funzioni sono i +seguenti: +\begin{prototype}{sys/socket.h} + {int inet\_pton(int af, const char *src, void *addr\_ptr)} Converte la + stringa puntata da \texttt{src} nell'indirizzo IP da memorizzare + all'indirizzo puntato da \texttt{addr\_ptr}, la funzione restituisce un + valore positivo in caso di successo, e zero se la stringa non rappresenta un + indirizzo valido, e negativo se \var{af} specifica una famiglia di indirizzi + non valida. +\end{prototype} + +\begin{prototype}{sys/socket.h} + {char *inet\_ntop(int af, const void *addr\_ptr, char *dest, size\_t len)} + Converte la struttura dell'indirizzo puntata da \texttt{addr\_ptr} in una + stringa che viene copiata nel buffer puntato dall'indirizzo \texttt{dest}; + questo deve essere preallocato dall'utente e la lunghezza deve essere almeno \texttt{INET\_ADDRSTRLEN} in caso di indirizzi IPv4 e \texttt{INET6\_ADDRSTRLEN} per indirizzi IPv6; la lunghezza del buffer deve comunque venire specificata attraverso il parametro \texttt{len}. - + La funzione restituisce un puntatore non nullo a \texttt{dest} in caso di successo e un puntatore nullo in caso di fallimento, in quest'ultimo caso viene settata la variabile \texttt{errno} con il valore \texttt{ENOSPC} in caso le dimensioni dell'indirizzo eccedano la lunghezza specificata da - \texttt{len}. - -\end{itemize} - + \texttt{len} o \macro{ENOAFSUPPORT} in caso \var{af} non sia una famiglia di + indirizzi valida. +\end{prototype} + +Gli indirizzi vengono cnovertiti da/alle rispettive strutture di indirizzo +(\var{struct in\_addr} per IPv4, e \var{struct in6\_addr} per IPv6), che +devono essere precedentemente allocate e passate attraverso il puntatore +\var{addr\_ptr}; il parametro \var{dest} di \func{inet\_ntop} non può essere +nullo e deve essere allocato precedentemente. + +Il formato usato per gli indirizzi in formato di presentazione è la notazione +\textit{dotted decimal} per IPv4 e quella descritta in +\secref{sec:IP_ipv6_notation} per IPv6. \section{Il comportamento delle funzioni di I/O} \label{sec:sock_io_behav}