\label{sec:UDP_characteristics}
Come illustrato in \secref{sec:net_udp} UDP è un protocollo molto semplice che
-non supporta le connessioni e non è affidabile: i dati vengono inviati in
-forma di pacchetti, e non ne è assicurata né la effettiva ricezione né
-l'odinamento.
+non supporta le connessioni e non è affidabile: esso si appoggia direttamente
+sopra IP (per i dettagli sul protocollo si veda \secref{sec:udp_protocol}). I
+dati vengono inviati in forma di pacchetti, e non ne è assicurata né la
+effettiva ricezione né l'arrivo nell'ordine in cui vengono inviati. Il
+vantaggio del protocollo è la velocità, non è necessario trasmettere le
+informazioni di controllo ed il risultato è una trasmissione di dati più
+veloce ed immediata.
Questo significa che a differenza dei socket TCP i socket UDP non supportano
una comunicazione di tipo \textit{stream} in cui si ha a disposizione un
-flusso continuo di dati che può essere letto un po' alla volta, ma di tipo
-\textit{datagram}, in cui i dati arrivano in singoli blocchi che devono essere
-letti integralmente.
-
-Questo diverso comportamento significa anche che i socket UDP, pur restando
-nella famiglia \const{PF\_INET}\footnote{o \const{PF\_INET6} qualora si usasse
- invece il protocollo IPv6.} devono essere aperti quando si usa la funzione
-\func{socket} (si riveda quanto illustrato a suo tempo in
-\tabref{tab:sock_sock_valid_combinations}) utilizzando come valore per il tipo
-di socket \const{SOCK\_DGRAM}.
-
-Questa differenza comporta ovviamente il fatto che anche le modalità con cui
-si usano i socket UDP sono completamente diverse rispetto ai socket TCP, ed in
+flusso continuo di dati che può essere letto un po' alla volta, ma piuttosto
+una comunicazione di tipo \textit{datagram}, in cui i dati arrivano in singoli
+blocchi che devono essere letti integralmente.
+
+Questo diverso comportamento significa anche che i socket UDP, pur
+appartenendo alla famiglia \const{PF\_INET}\footnote{o \const{PF\_INET6}
+ qualora si usasse invece il protocollo IPv6, che pure supporta UDP.} devono
+essere aperti quando si usa la funzione \func{socket} (si riveda quanto
+illustrato a suo tempo in \tabref{tab:sock_sock_valid_combinations})
+utilizzando per il tipo di socket il valore \const{SOCK\_DGRAM}.
+
+Questa differenza comporta ovviamente che anche le modalità con cui si usano i
+socket UDP sono completamente diverse rispetto ai socket TCP, ed in
particolare non esistendo il concetto di connessione non esiste il meccanismo
-del \textit{three way handshake} nè quello di stati del protocollo, in realtà
-tutto quello che avviene nella comunicazione attraverso dei socket UDP è la
-trasmissione di un pacchetto da un client ad un server o viceversa, secondo lo
-schema illustrato in \figref{fig:UDP_packet-exchange}.
+del \textit{three way handshake} nè quello degli stati del protocollo. In
+realtà tutto quello che avviene nella comunicazione attraverso dei socket UDP
+è la trasmissione di un pacchetto da un client ad un server o viceversa,
+secondo lo schema illustrato in \figref{fig:UDP_packet-exchange}.
\begin{figure}[htb]
\centering
\label{fig:UDP_packet-exchange}
\end{figure}
-Anche se UDP è completamente diverso rispetto a TCP resta identica
+Come illustrato in \figref{fig:UDP_packet-exchange} la struttura generica di
+un server UDP prevede, una volta creato il socket, la chiamata a \func{bind}
+per mettersi in ascolto dei dati. Questa è l'unica parte comune con un server
+TCP: non essendovi il concetto di connessione le funzioni \func{listen} ed
+\func{accept} non sono mai utilizzate nel caso di server UDP. La ricezione dei
+dati dal client avviene attraverso la funzione \func{recvfrom}, mentre una
+eventuale risposta sarà inviata con la funzione \func{sendto}.
+
+Da parte del client invece, una volta creato il socket non sarà necessario
+connettersi con \func{connect} (anche se, come vedremo in
+\secref{sec:UDP_connect}, è possibile usare questa funzione, con un
+significato comunque diverso) ma si potrà effettuare direttamente una
+richiesta inviando un pacchetto con la funzione \func{sendto} e si potrà
+leggere una eventuale risposta con la funzione \func{recvfrom}.
+Anche se UDP è completamente diverso rispetto a TCP resta identica la
+possibilità di gestire più canali di comunicazione fra due macchine
+utilizzando le porte. In questo caso il server dovrà usare comunque la
+funzione \func{bind} per scegliere la porta su cui ricevere i dati, e come nel
+caso dei socket TCP si potrà usare il comando \cmd{netstat}\footnote{per
+ ottenere il risultato mostrato occorre usare le opzioni \texttt{-anu}.} per
+verificare quali socket sono in ascolto:
+\begin{verbatim}
+Active Internet connections (servers and established)
+Proto Recv-Q Send-Q Local Address Foreign Address State
+udp 0 0 0.0.0.0:32768 0.0.0.0:*
+udp 0 0 192.168.1.2:53 0.0.0.0:*
+udp 0 0 127.0.0.1:53 0.0.0.0:*
+udp 0 0 0.0.0.0:67 0.0.0.0:*
+\end{verbatim}
+in questo caso abbiamo attivi il DNS (sulla porta 53, e sulla 32768 per la
+connessione di controllo del server \cmd{named}) ed un server DHCP (sulla
+porta 67).
+
+Si noti però come in questo caso la colonna che indica lo stato sia vuota. I
+socket UDP infatti non hanno uno stato. Inoltre anche in presenza di traffico
+non si avranno indicazioni delle connessioni attive, proprio perché non esiste
+niente di simile per i socket UDP, il kernel si limita infatti a ricevere i
+pacchetti ed inviarli al processo in ascolto sulla porta cui essi sono
+destinati, oppure a scartarli inviando un messaggio \textit{ICMP port
+ unreachable} qualora non vi sia nessun processo in ascolto.
\subsection{Le funzioni \func{sendto} e \func{recvfrom}}
\label{sec:UDP_sendto_recvfrom}
-Come accennato le due funzioni principali usate per la trasmissione di dati
-attraverso i socket UDP, ma in generale attraverso qualunque socket che
-preveda una comunicazione a pacchetti, sono \func{sendto} e \func{recvfrom}.
+Come accennato in \secref{sec:UDP_characteristics} le due funzioni principali
+usate per la trasmissione di dati attraverso i socket UDP, sono \func{sendto}
+e \func{recvfrom}. La necessità di usare queste funzioni è dovuta al fatto che
+non esistendo con UDP il concetto di connessione, non si ha neanche a
+disposizione un \textsl{socket connesso} su cui sia possibile usare
+direttamente \func{read} e \func{write} avendo già stabilito (grazie alla
+chiamata ad \func{accept} che lo associa ad una connessione) quali sono
+sorgente e destinazione dei dati.
+
+Per questo motivo nel caso di UDP diventa essenziale utilizzare queste due
+funzioni, che sono comunque usabili in generale per la trasmissione di dati
+attraverso qualunque tipo di socket, dato che esse hanno la caratteristica di
+provvedere tre argomenti aggiuntivi che consentono di specificare destinazione
+o origine dei dati trasmessi. La prima delle due funzioni è \funcd{sendto} ed
+il suo prototipo\footnote{il prototipo illustrato è quello utilizzato dalle
+ \acr{glibc}, che seguono le \textit{Single Unix Specification}, l'argomento
+ \param{flags} era di tipo \type{int} nei vari BSD4.*, mentre nelle
+ \acr{libc4} e \acr{libc5} veniva usato un \type{unsigned int}; l'argomento
+ \param{len} era \type{int} nei vari BSD4.* e nelle \acr{libc4}, ma
+ \type{size\_t} nelle \acr{libc5}; infine l'argomento \param{tolen} era
+ \type{int} nei vari BSD4.* nelle \acr{libc4} e nelle \acr{libc5}.} è:
+\begin{functions}
+ \headdecl{sys/types.h}
+ \headdecl{sys/socket.h}
+
+ \funcdecl{ssize\_t sendto(int sockfd, const void *buf, size\_t len, int
+ flags, const struct sockaddr *to, socklen\_t tolen)}
+
+ Trasmette un messaggio ad un altro socket.
+
+ \bodydesc{La funzione restituisce il numero di caratteri inviati in caso di
+ successo e -1 per un errore; nel qual caso \var{errno} viene impostata al
+ rispettivo codice di errore:
+ \begin{errlist}
+ \item[\errcode{EAGAIN}] il socket è in modalità non bloccante, ma
+ l'operazione richede che la funzione si blocchi.
+ \item[\errcode{ECONNRESET}] l'altro capo della comunicazione ha resettato la
+ conessione.
+ \item[\errcode{EDESTADDRREQ}] il socket non è di tipo connesso, e non si è
+ specificato un indirizzo di destinazione.
+ \item[\errcode{EISCONN}] il socket è già connesso, ma si è specificato un
+ destinatario.
+ \item[\errcode{EMSGSIZE}] il tipo di socket richiede l'invio dei dati in un
+ blocco unico, ma la dimensione del messaggio lo rende impossibile.
+ \item[\errcode{ENOBUFS}] la coda di uscita dell'interfaccia è già piena (di
+ norma Linux non usa questo messaggio ma scarta silenziosamente i
+ pacchetti).
+ \item[\errcode{ENOTCONN}] il socket non è connesso e non si è specificata
+ una destinazione.
+ \item[\errcode{EOPNOTSUPP}] il valore di \param{flag} non è appropriato per
+ il tipo di socket usato.
+ \item[\errcode{EPIPE}] il capo locale della connessione è stato chiuso, si
+ riceverà anche un segnale di \const{SIGPIPE}, a meno di non aver impostato
+ \const{MSG\_NOSIGNAL} in \param{flags}.
+ \end{errlist}
+ ed anche \errval{EFAULT}, \errval{EBADF}, \errval{EINVAL}, \errval{EINTR},
+ \errval{ENOMEM}, \errval{ENOTSOCK} più gli eventuali altri errori relativi
+ ai protocolli utilizzati.}
+\end{functions}
+
+I primi tre argomenti sono identici a quelli della funzione \func{write} e
+specificano il socket \param{sockfd} a cui si fa riferimento ed il buffer
+\param{buf} (e relativa lunghezza \param{len}) che contiene i dati da inviare.
+Come per \func{write} la funzione ritorna il numero di byte inviati; nel caso
+di UDP però questo deve sempre corrispondere alla dimensione totale
+specificata da \param{len} in quanto i dati vengono sempre inviati in forma di
+pacchetto e non possono essere spezzati in invii successivi. Qualora non ci
+sia spazio nel buffer di uscita la funzione si blocca (a meno di non avere
+aperto il socket in modalità non bloccante), se invece non è possibile inviare
+il messaggio all'interno di un unico pacchetto essa fallisce con l'errore di
+\errcode{EMSGSIZE}.
+
+I due argomenti \param{to} e \param{tolen} servono a specificare la
+destinazione del messaggio da inviare, e prendono l'indirizzo di quest'ultima,
+nella stessa forma in cui lo si specificherebbe per \func{connect}: \param{to}
+deve cioè contere l'indirizzo IP e la porta di destinazione cui si vogliono
+inviare i dati e \param{tolen} la relativa dimensione.
+
+Se il socket è di un tipo che prevede le connessioni, questo deve essere già
+connesso prima di eseguire la funzione (altrimenti si avrà un errore di
+\errcode{ENOTCONN}) ed inoltre questi due ultimi argomenti devono essere
+inizializzati rispettivamente a \const{NULL} e 0 (di solito vengono ignorati,
+ma si potrebbe ricevere altrimenti anche un errore di \errcode{EISCONN}).
+
+Infine l'argomento \param{flags} è un intero usato come maschera binaria che
+permette di impostare una serie di modalità di funzionamento della
+comunicazione attraverso il socket (come \const{MSG\_NOSIGNAL} che impedisce
+l'invio del segnale \const{SIGPIPE} quando si è già chiuso il capo locale
+della connessione). Torneremo con maggiori dettagli sul significato di questo
+argomento in \secref{sec:xxx_sendmsg}, per il momento ci si può limitare ad
+usare sempre un valore nullo.
+
+La seconda funzione utilizzata nella comunicazione fra socket UDP è
+\funcd{recvfrom} che serve invece a ricevere i dati inviati da un altro
+socket, il suo prototipo\footnote{il prototipo è quello delle \acr{glibc} che
+ seguono le \textit{Single Unix Specification}, i vari BSD4.*, le \acr{libc4}
+ e le \acr{libc5} usano un \type{int} come valore di ritorno; per gli
+ argomenti \param{flags} e \param{len} vale quanto detto a proposito di
+ \func{sendto}; infine l'argomento \param{fromlen} è \type{int} per i vari
+ BSD4.*, le \acr{libc4} e le \acr{libc5}.} è:
+\begin{functions}
+ \headdecl{sys/types.h}
+ \headdecl{sys/socket.h}
+
+ \funcdecl{ssize\_t recvfrom(int sockfd, const void *buf, size\_t len, int
+ flags, const struct sockaddr *from, socklen\_t *fromlen)}
+
+ Riceve un messaggio ad un altro socket.
+
+ \bodydesc{La funzione restituisce il numero di byte ricevuti in caso di
+ successo e -1 in caso di errore; nel qual caso \var{errno} assumerà il
+ valore:
+ \begin{errlist}
+ \item[\errcode{EAGAIN}] il socket è in modalità non bloccante, ma
+ l'operazione richede che la funzione si blocchi, oppure si è impostato un
+ timeout in ricezione e questo è scaduto.
+ \item[\errcode{ECONNREFUSED}] l'altro capo della comunicazione ha rifiutato
+ la connessione (in genere perché il relativo servizio non è disponibile).
+ \item[\errcode{ENOTCONN}] il socket è di tipo connesso, ma non si è eseguita
+ la connessione.
+ \end{errlist}
+ ed anche \errval{EFAULT}, \errval{EBADF}, \errval{EINVAL}, \errval{EINTR},
+ \errval{ENOMEM}, \errval{ENOTSOCK} più gli eventuali altri errori relativi
+ ai protocolli utilizzati.}
+\end{functions}
+
+Come per \func{sendto} i primi tre argomenti sono identici agli analoghi di
+\func{read}: dal socket vengono letti \param{len} byte che vengono salvati nel
+buffer \param{buf}. A seconda del tipo di socket (se di tipo \textit{datagram}
+o \textit{stream}) inoltre i byte in eccesso che non sono stati letti possono
+rispettivamente andare persi o restare disponibili per una lettura
+successiva.
+
+
+
+
+
+\subsection{L'uso della funzione \func{connect} con i socket UDP}
+\label{sec:UDP_connect}
+
+Come illustrato in \secref{sec:UDP_characteristics} essendo i socket UDP privi
+di connessione non è necessario per i client usare \func{connect} prima di
+iniziare una comunicazione con un server.
+
\section{I socket \textit{Unix domain}}
-\label{sec:UDP_socket}
+\label{sec:unix_socket}
Benché i socket Unix domain non siano strattamente attinenti alla rete, in
quanto definiscono una interfaccia di comunicazione locale alla singola