Aggiunto l'header nell'environment per scrivere i prototipi delle funzioni e
authorSimone Piccardi <piccardi@gnulinux.it>
Fri, 11 May 2001 23:42:51 +0000 (23:42 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Fri, 11 May 2001 23:42:51 +0000 (23:42 +0000)
risistemate tutte le relative occorrenze.

Quasi completata la descrizione di listen (con tanto di fisime sul syn flood
e relativi annessi).

elemtcp.tex
filedir.tex
macro.tex
main.tex
socket.tex

index 5e5a69cd3c782f2cda80f1e40a864c79352e8d58..ca1a94b3562ba63454d58d278a53beda70dc3ede 100644 (file)
@@ -634,10 +634,10 @@ cio
 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
@@ -713,11 +713,10 @@ di effettuare una assegnazione del tipo:
 \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
@@ -819,9 +818,20 @@ necessario effettuare una \texttt{bind}.
 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.
@@ -832,6 +842,66 @@ sostanza l'effetto della funzione 
 \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}
index ecabab0f6aa07cc148f8df4c684a27d2ec2d062e..34e64d9ddc6929cf1bc41a6f9cf8ee6886493daf 100644 (file)
@@ -188,10 +188,10 @@ particolare preferenza rispetto agli altri.
 
 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}.
   
@@ -238,10 +238,9 @@ riparare il filesystem).
 
 
 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.
   
@@ -325,7 +324,8 @@ riferimento.
 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}.
   
@@ -350,10 +350,11 @@ dichiarate nell'header file \texttt{unistd.h}.
 \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.
@@ -413,9 +414,9 @@ un processo figlio, la directory corrente della shell diventa anche la
 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
@@ -459,13 +460,13 @@ riferirsi ad esse tramite il file descriptor dell'interfaccia a basso livello,
 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
index 2f4ea86a4cc19f39f452e43c63bc54800b410775..9feadaa9d15e36a1bdb230970d1c28232e7e0118 100644 (file)
--- a/macro.tex
+++ b/macro.tex
@@ -60,20 +60,24 @@ tab.~\thechapter.\theusercount}
 %
 % 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}}
-
-
index 213648c85138ea0f02726b796da81bd5f52878ab..097db57d8bb106682ad1e1f5e5fb69122ecc901a 100644 (file)
--- a/main.tex
+++ b/main.tex
 
 \end{document}
 
-
-
-
index 4f18f9f098d4f915875d4c56d69e0adc440e86be..ecf1a9eeb826183a1a6377e0cf76e52a1630e59a 100644 (file)
@@ -75,14 +75,13 @@ 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
+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
@@ -534,24 +533,27 @@ esempio nel caso dell'intero a 16 bit ci si ritrover
 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}
@@ -571,10 +573,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 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
@@ -582,15 +583,16 @@ 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{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
@@ -598,7 +600,7 @@ indicare la stringa. Dette funzioni sono:
   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