man page è:
\begin{prototype}{sys/socket.h}{int listen(int sockfd, int backlog)}
-
La funzione pone il socket specificato da \texttt{sockfd} in modalità
- passiva e predispone una coda per le connessioni in arrivo pari a
- \texttt{backlog}. La funzione si può applicare solo a socket di tipo
+ passiva e predispone una coda per le connessioni in arrivo di lunghezza pari
+ a \texttt{backlog}. La funzione si può applicare solo a socket di tipo
\texttt{SOCK\_STREAM} o \texttt{SOCK\_SEQPACKET}.
La funzione restituisce 0 in caso di successo e -1 in caso di errore. I
\item \texttt{EBADF} L'argomento \texttt{sockfd} non è un file descriptor
valido.
\item \texttt{ENOTSOCK} L'argomento \texttt{sockfd} non è un socket.
- \item \texttt{EOPNOTSUPP} The socket is not of a type that supports the lis
- ten operation.
+ \item \texttt{EOPNOTSUPP} Il socket è di un tipo che non supporta questa
+ operazione.
\end{errlist}
\end{prototype}
kernel non supportavano neanche valori superiori, ma la situazione corrente è
molto cambiata dagli anni '80 e con server web che possono sopportare diversi
milioni di connessioni al giorno un tale valore non è più adeguato. Non esiste
-comunque una risposta univoca
+comunque una risposta univoca per la scelta del valore, per questo non
+conviene specificare questo valore con una costante (il cui cambiamento
+richiederebbe la ricompilazione del server) ma usare piuttosto una variabile
+di ambiente (vedi \secref{sec:xxx_env_var}). Lo Stevens tratta accuratamente
+questo argomento, con esempi presi da casi reali su web server, ed in
+particolare evidenzia come non sia più vero che la ragione della coda è quella
+di gestire il caso in cui il server è occupato fra chiamate successive alla
+\texttt{accept} (per cui la coda più occupata sarebbe quella delle connessioni
+compeltate), ma è invece necessaria a gestire la presenza di un gran numero di
+SYN in attesa di completare il three-way handshake.
+
+Come accennato nel caso del TCP se un SYN arriva con tutte le code piene, il
+pacchetto sarà ignorato. Questo viene fatto perché la condizione delle code
+piene è transitoria, e se il client ristrasmette il SYN è probabile che
+passato un po' di tempo possa trovare lo spazio per una nuova connessione. Se
+invece si rispondesse con un RST la \texttt{connect} del client ritornerebbe
+con una condizione di errore, mentre questo è il tipico caso in cui è si può
+lasciare la gestione della connessione alla ritrasmissione prevista dal
+protocollo TCP.
\subsection{La funzione \texttt{accept}}
\label{sec:TCPel_func_accept}
+La funzione \texttt{accept} è chiamata da un server TCP per gestire la
+connessione una volta che sia stato completato il three way handshake, la
+funzione restituisce un nuovo socket descriptor su cui si potrà operare per
+effettuare la comunicazione. Se non ci sono connessioni completate il processo
+viene messo in attesa. Il prototipo della funzione è il seguente:
+
+
+\begin{prototype}{sys/socket.h}
+{int listen(int sockfd, struct sockaddr *addr, socklen\_t *addrlen)}
+ La funzione estrae la prima connessione completa relativa al socket
+ \texttt{sockfd} in attesa sulla coda delle connessioni complete che associa
+ nuovo socket con le stesse caratteristiche di \texttt{sockfd} (restituito
+ dalla funzione stessa). Il socket originale non viene toccato. Nella
+ struttura \texttt{addr} e nella variabile \texttt{addrlen} vengono
+ restituiti indirizzo e relativa lunghezza del client che si è connesso.
+
+ La funzione restituisce un numero di socket descriptor positivo in caso di
+ successo e -1 in caso di errore, nel qual caso la variabile \texttt{errno}
+ viene settata ai seguenti valori:
+
+ \begin{errlist}
+ \item \texttt{EBADF} L'argomento \texttt{sockfd} non è un file descriptor
+ valido.
+ \item \texttt{ENOTSOCK} L'argomento \texttt{sockfd} non è un socket.
+ \item \texttt{EOPNOTSUPP} Il socket è di un tipo che non supporta questa
+ operazione.
+ \item \texttt{EAGAIN} or \item \texttt{EWOULDBLOCK} Il socket è stato
+ settato come non bloccante, e non ci sono connessioni in attesa di essere
+ accettate.
+ \item \texttt{EFAULT} The addr parameter is not in a writable part of the
+ user address space.
+ \item \texttt{EPERM} Firewall rules forbid connection.
+
+ \item \texttt{ENOBUFS, ENOMEM} Not enough free memory. This often means
+ that the memory allocation is limited by the socket buffer limits, not by
+ the system memory.
+ \end{errlist}
+\end{prototype}
+
+La funzione può essere usata solo con socket che supportino la connessione
+(cioè di tipo \texttt{SOCK\_STREAM}, \texttt{SOCK\_SEQPACKET} o
+\texttt{SOCK\_RDM}). Per alcuni protocolli che richiedono una conferma
+esplicita della connessione, (attualmenente in linux solo DECnet ha questo
+comportamento), la funzione opera solo l'estrazione dalla coda delle
+connessioni, la conferma della connessione viene fatta implicitamente dalla
+prima chiamata ad una \texttt{read} o una \texttt{write} mentre il rifiuto
+della connessione viene fatta con la funzione \texttt{close}.
+
+I due parametri \texttt{cliaddr} e \texttt{addrlen} (si noti che quest'ultimo
+è passato per indirizzo per avere indietro il valore) sono usati per ottenere
+l'indirizzo del client da cui proviene la connessione. Prima della chiamata
+\texttt{addrlen} deve essere inizializzato alle dimensioni della struttura il
+cui indirizzo è passato come parametro in \texttt{cliaddr}, al rientro della
+funzione \texttt{addrlen} conterrà il numero di bytes scritti dentro
+\texttt{cliaddr}.
+
+Se la funzione ha successo restituisce un nuovo socket descriptor, detto
+\textit{connected socket}, su cui è agganciata la connessione che il client
+TCP ha effettuato verso il socket \texttt{sockfd}. Quest'ultimo, che viene
+chiamato invece \textit{listening socket}, deve essere stato creato in
+precedenza e messo in ascolto con \texttt{listen}, e non viene toccato dalla
+funzione.
+
+Questa distinzione è essenziale per capire
+
+
\section{Una semplice implementazione del servizio \texttt{echo} su TCP}
\label{sec:TCPel_echo_example}
+
+Veniamo ora ad una applicazione