From ae0f5a752ec86bf15b78031f4b33664a8c0b515b Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Fri, 11 May 2001 23:42:51 +0000 Subject: [PATCH] Aggiunto l'header nell'environment per scrivere i prototipi delle funzioni e risistemate tutte le relative occorrenze. Quasi completata la descrizione di listen (con tanto di fisime sul syn flood e relativi annessi). --- elemtcp.tex | 88 +++++++++++++++++++++++++++++++++++++++++++++++------ filedir.tex | 31 ++++++++++--------- macro.tex | 16 ++++++---- main.tex | 3 -- socket.tex | 54 ++++++++++++++++---------------- 5 files changed, 133 insertions(+), 59 deletions(-) diff --git a/elemtcp.tex b/elemtcp.tex index 5e5a69c..ca1a94b 100644 --- a/elemtcp.tex +++ b/elemtcp.tex @@ -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} diff --git a/filedir.tex b/filedir.tex index ecabab0..34e64d9 100644 --- a/filedir.tex +++ b/filedir.tex @@ -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 diff --git a/macro.tex b/macro.tex index 2f4ea86..9feadaa 100644 --- 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}} - - diff --git a/main.tex b/main.tex index 213648c..097db57 100644 --- a/main.tex +++ b/main.tex @@ -119,6 +119,3 @@ \end{document} - - - diff --git a/socket.tex b/socket.tex index 4f18f9f..ecf1a9e 100644 --- a/socket.tex +++ b/socket.tex @@ -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 -- 2.30.2