risistemate tutte le relative occorrenze.
Quasi completata la descrizione di listen (con tanto di fisime sul syn flood
e relativi annessi).
server per specificare la porta (e gli eventuali indirizzi locali) su cui poi
ci si porrà in ascolto.
-Il prototipo della funzione, definito in \texttt{sys/socket.h}, è il seguente:
+Il prototipo della funzione è il seguente:
-\begin{prototype}{int bind(int sockfd, const struct sockaddr *serv\_addr,
- socklen\_t addrlen) }
+\begin{prototype}{sys/socket.h}
+{int bind(int sockfd, const struct sockaddr *serv\_addr, socklen\_t addrlen)}
Il primo argomento è un file descriptor ottenuto da una precedente chiamata
a \texttt{socket}, mentre il secondo e terzo argomento sono rispettivamente
\label{sec:TCPel_func_connect}
La funzione \texttt{connect} è usata da un client TCP per stabilire la
-connessione con un server TCP, il prototipo della funzione, definito in
-\texttt{sys/socket.h}, è il seguente:
+connessione con un server TCP, il prototipo della funzione è il seguente:
-\begin{prototype}{int connect(int sockfd, const struct sockaddr *serv\_addr,
- socklen\_t addrlen) }
+\begin{prototype}{sys/socket.h}
+{int connect(int sockfd, const struct sockaddr *serv\_addr, socklen\_t addrlen)}
Il primo argomento è un file descriptor ottenuto da una precedente chiamata
a \texttt{socket}, mentre il secondo e terzo argomento sono rispettivamente
La funzione \texttt{listen} è usata per usare un socket in modalità passiva,
cioè, come dice il nome, per metterlo in ascolto di eventuali connessioni; in
sostanza l'effetto della funzione è di portare il socket dallo stato
-\texttt{CLOSED} a quello \texttt{LISTEN}.
+\texttt{CLOSED} a quello \texttt{LISTEN}. In genere si chiama la funzione in
+un server dopo le chiamate a \texttt{socket} e \texttt{bind} e prima della
+chiamata ad \texttt{accept}. Il prototipo della funzione come definito dalla
+man page è:
-\begin{prototype}{int listen(int sockfd, int backlog)}
+\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
+ \texttt{SOCK\_STREAM} o \texttt{SOCK\_SEQPACKET}.
+
+ La funzione restituisce 0 in caso di successo e -1 in caso di errore. I
+ codici di errore restituiti in \texttt{errno} sono i seguenti:
\begin{errlist}
\item \texttt{EBADF} L'argomento \texttt{sockfd} non è un file descriptor
valido.
\end{prototype}
+Il parametro \texttt{backlog} indica il numero massimo di connessioni pendenti
+accettate; se esso viene ecceduto il client riceverà una errore di tipo
+\texttt{ECONNREFUSED}, o se il protocollo, come nel caso del TCP, supporta la
+ritrasmissione, la richiesta sarà ignorata in modo che la connessione possa
+essere ritentata.
+
+Per capire meglio il significato di tutto ciò occorre approfondire la modalità
+con cui il kernel tratta le connessioni in arrivo. Per ogni socket in ascolto
+infatti vengono mantenute due code:
+\begin{enumerate}
+\item Una coda delle connessioni incomplete (\textit{incomplete connection
+ queue} che contiene una entrata per ciascun SYN arrivato per il quale si
+ sta attendendo la conclusione del three-way handshake. Questi socket sono
+ tutti nello stato \texttt{SYN\_RECV}.
+\item Una coda delle connessioni complete (\textit{complete connection queue}
+ che contiene una entrata per ciascuna connessione per le quali il three-way
+ handshake è stato completato ma ancora \texttt{accept} non è ritornata.
+\end{enumerate}
+
+Lo schema di funzionamento è descritto in \nfig, quando arriva un SYN da un
+client il server crea una nuova entrata nella coda delle connessioni
+incomplete, e poi risponde con il SYN$+$ACK. La entrata resterà nella coda
+delle connessioni incomplete fino al ricevimento dell'ACK dal client o fino ad
+un timeout. Nel caso di completamento del three-way handshake l'entrata viene
+sostata nella coda delle connessioni complete. Quando il processo chiama la
+funzione \texttt{accept} (vedi \secref{sec:TCPel_func_accept}) la prima
+entrata nella coda delle connessioni complete è passata al programma, o, se la
+coda è vuota, il processo viene posto in attesa e risvegliato all'arrivo della
+prima connessione completa.
+
+Storicamente il valore del parametro \texttt{backlog} era corrispondente al
+massimo valore della somma del numero di entrate possibili per ciascuna di
+dette code. Stevens riporta che BSD ha sempre applicato un fattore di 1.5 al
+valore, e provvede una tabella con i risultati ottenuti con vari kernel,
+compreso linux 2.0, che mostrano le differenze fra diverse implementazioni.
+
+Ma in linux il significato di questo valore è cambiato a partire dal kernel
+2.2 per prevenire l'attacco chiamato \texttt{syn flood}. Questo si basa
+sull'emissione da parte dell'attaccante di un grande numero di pacchetti SYN
+indirizzati verso una porta forgiati con indirizzo IP fasullo \footnote{con la
+ tecnica che viene detta \textit{ip spoofing}} così che i SYN$+$ACK vanno
+perduti la coda delle connessioni incomplete viene saturata, impedendo di
+fatto le connessioni.
+
+Per ovviare a questo il significato del \texttt{backlog} è stato cambiato a
+significare la lunghezza della coda delle connessioni complete. La lunghezza
+della coda delle connessioni incomplete può essere ancora controllata usando
+la \texttt{sysctl} o scrivendola direttamente in
+\texttt{/proc/sys/net/ipv4/tcp\_max\_syn\_backlog}. Quando si attiva la
+protezione dei syncookies però (con l'opzione da compilare nel kernel e da
+attivare usando \texttt{/proc/sys/net/ipv4/tcp\_syncookies}) questo valore
+viene ignorato e non esiste più un valore massimo.
+
+La scelta storica per il valore di questo parametro è di 5, e alcuni vecchi
+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
+
+
\subsection{La funzione \texttt{accept}}
\label{sec:TCPel_func_accept}
Per aggiungere un nome ad un inode si utilizza la funzione \texttt{link}; si
suole chiamare questo tipo di associazione un collegamento diretto (o
-\textit{hard link}). Il prototipo della funzione, definita in
-\texttt{unistd.h}, e le sue caratteritiche principali, come risultano dalla
-man page, sono le seguenti:
-\begin{prototype}{int link(const char * oldname, const char * newname)}
+\textit{hard link}). Il prototipo della funzione e le sue caratteritiche
+principali, come risultano dalla man page, sono le seguenti:
+\begin{prototype}{unistd.h}
+{int link(const char * oldname, const char * newname)}
Crea un nuovo collegamento diretto al file indicato da \texttt{oldname}
dandogli nome \texttt{newname}.
La rimozione di un file (o più precisamente della voce che lo referenzia) si
-effettua con la funzione \texttt{unlink}; il suo prototipo, definito in
-\texttt{unistd.h} è il seguente:
+effettua con la funzione \texttt{unlink}; il suo prototipo è il seguente:
-\begin{prototype}{int unlink(const char * filename)}
+\begin{prototype}{unistd.h}{int unlink(const char * filename)}
Cancella il nome specificato dal pathname nella relativa directory e
decrementa il numero di riferimenti nel relativo inode.
Le funzioni per operare sui link simbolici sono le seguenti, esse sono tutte
dichiarate nell'header file \texttt{unistd.h}.
-\begin{prototype}{int symlink(const char * oldname, const char * newname)}
+\begin{prototype}{unistd.h}
+{int symlink(const char * oldname, const char * newname)}
Crea un nuovo link simbolico al file indicato da \texttt{oldname} dandogli
nome \texttt{newname}.
\label{sec:filedir_dir_creat_rem}
Per creare una nuova directory si può usare la seguente funzione, omonima
-dell'analogo comando di shell \texttt{mkdir}; per accedere alla funzioni il
-programma deve includere il file \texttt{sys/stat.h}.
+dell'analogo comando di shell \texttt{mkdir}; per accedere ai tipi usati
+programma deve includere il file \texttt{sys/types.h}.
-\begin{prototype}{char * mkdir (const char * dirname, mode\_t mode)}
+\begin{prototype}{sys/stat.h}
+{int mkdir (const char * dirname, mode\_t mode)}
Questa funzione crea una nuova directory vuota con il nome indicato da
\texttt{dirname}, assegnandole i permessi indicati da \texttt{mode}. Il nome
può essere indicato con il pathname assoluto o relativo.
directory corrente di qualunque comando da essa lanciato.
Le funzioni qui descritte servono esaminare e cambiare la directory di lavoro
-corrente. I prototipi di queste funzioni sono dichiarati in \texttt{unistd.h}.
+corrente.
-\begin{prototype}{char * getcwd (char * buffer, size\_t size)}
+\begin{prototype}{unistd.h}{char * getcwd (char * buffer, size\_t size)}
Restituisce il filename completo della directory di lavoro corrente nella
stringa puntata da \texttt{buffer}, che deve essere precedentemente
allocata, per una dimensione massima di \texttt{size}. Si può anche
e non solo tramite il filename; per questo motivo ci sono due diverse funzioni
per cambiare directory di lavoro.
-\begin{prototype}{int chdir (const char * pathname)}
+\begin{prototype}{unistd.h}{int chdir (const char * pathname)}
Come dice il nome (che significa \textit{change directory}) questa funzione
serve a cambiare la directory di lavoro a quella speficata dal pathname
contenuto nella stringa \texttt{pathname}.
\end{prototype}
-\begin{prototype}{int fchdir (int filedes)}
+\begin{prototype}{unistd.h}{int fchdir (int filedes)}
Analoga alla precedente, ma usa un file descriptor invece del pathname.
Entrambe le funzioni restituiscono zero in caso di successo e -1 per un
%
% Macro to create a special environment for function prototypes
%
-\newenvironment{prototype}[1]{
+\newenvironment{prototype}[2]{
\center
- \begin{minipage}[c]{14cm}
- \par \texttt{#1}
\footnotesize
+ \begin{minipage}[c]{14cm}
+ \par \texttt{\#include <#1>}
+% \par \
+ \par \texttt{#2}
+% \begin{lstlisting}{}
+% #1
+% #2
+% \end{lstlisting}
\begin{list}{}{}
\item }
{ \end{list}
\par
-\normalsize
\par \texttt{ }
\end{minipage}
+\normalsize
\par
}
\newenvironment{errlist}{\begin{description}}{\end{description}}
-
-
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
+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{prototype}{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
suddiviso scambiati di posto, e ne sarà quindi invertito l'ordine di lettura
per cui, per riavere il valore originale dovrenno 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
-funzioni sono:{
-\begin{prototype}{unsigned long int htonl(unsigned long int hostlong)}
+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{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.
\end{prototype}
-\begin{prototype}{unsigned sort int htons(unsigned short int hostshort)}
+\begin{prototype}{netinet/in.h}
+{unsigned sort int htons(unsigned short int hostshort)}
Converte l'intero a 16 bit \texttt{hostshort} dal formato della macchina a
quello della rete.
\end{prototype}
-\begin{prototype}{unsigned long int ntonl(unsigned long int netlong)}
+\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.
\end{prototype}
-\begin{prototype}{unsigned sort int ntons(unsigned short int netshort)}
+\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{prototype}
\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 normalente.
Le prime tre funzioni di manipolazione riguardano la conversione degli
indirizzi IPv4 da una stringa in cui il numero di IP è espresso secondo la
\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{prototype}{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}{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
valido, non può essere usata con questa funzione; per questo motivo essa è
generalmente deprecata in favore della precedente.
\end{prototype}
-\begin{prototype}{char *inet\_ntoa(struct in\_addr addrptr)}
+\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