%% tcpsock.tex
%%
-%% Copyright (C) 2000-2011 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2000-2012 Simone Piccardi. Permission is granted to
%% copy, distribute and/or modify this document under the terms of the GNU Free
%% Documentation License, Version 1.1 or any later version published by the
%% Free Software Foundation; with the Invariant Sections being "Un preambolo",
connessione. Normalmente vengono usate le seguenti opzioni:
\begin{itemize}
-\item \textit{MSS option}, dove MMS sta per \itindex{Maximum~Segment~Size}
- \textit{Maximum Segment Size}, con questa opzione ciascun capo della
- connessione annuncia all'altro il massimo ammontare di dati che vorrebbe
- accettare per ciascun segmento nella connessione corrente. È possibile
- leggere e scrivere questo valore attraverso l'opzione del socket
- \const{TCP\_MAXSEG} (vedi sez.~\ref{sec:sock_tcp_udp_options}).
+\item \textit{MSS option}, dove MMS sta per
+ \itindex{Maximum~Segment~Size~(MSS)} \textit{Maximum Segment Size}, con
+ questa opzione ciascun capo della connessione annuncia all'altro il massimo
+ ammontare di dati che vorrebbe accettare per ciascun segmento nella
+ connessione corrente. È possibile leggere e scrivere questo valore
+ attraverso l'opzione del socket \const{TCP\_MAXSEG} (vedi
+ sez.~\ref{sec:sock_tcp_udp_options}).
\item \textit{window scale option}, il protocollo TCP implementa il controllo
di flusso attraverso una \itindex{advertised~window} \textit{advertised
\end{itemize}
-La MSS \itindex{Maximum~Segment~Size} è generalmente supportata da quasi tutte
-le implementazioni del protocollo, le ultime due opzioni (trattate
+La MSS \itindex{Maximum~Segment~Size~(MSS)} è generalmente supportata da quasi
+tutte le implementazioni del protocollo, le ultime due opzioni (trattate
nell'\href{http://www.ietf.org/rfc/rfc1323.txt}{RFC~1323}) sono meno comuni;
vengono anche dette \textit{long fat pipe options} dato che questo è il nome
che viene dato alle connessioni caratterizzate da alta velocità o da ritardi
\end{figure}
La connessione viene iniziata dal client che annuncia una
-\itindex{Maximum~Segment~Size} MSS di 1460, un valore tipico con Linux per
-IPv4 su Ethernet, il server risponde con lo stesso valore (ma potrebbe essere
-anche un valore diverso).
+\itindex{Maximum~Segment~Size~(MSS)} MSS di 1460, un valore tipico con Linux
+per IPv4 su Ethernet, il server risponde con lo stesso valore (ma potrebbe
+essere anche un valore diverso).
Una volta che la connessione è stabilita il client scrive al server una
richiesta (che assumiamo stare in un singolo segmento, cioè essere minore dei
l'elenco delle porte assegnate dalla IANA (la \textit{Internet Assigned Number
Authority}) ma l'elenco viene costantemente aggiornato e pubblicato su
internet (una versione aggiornata si può trovare all'indirizzo
-\href{http://www.iana.org/assignments/port-numbers}
-{\textsf{http://www.iana.org/assignments/port-numbers}}); inoltre in un
-sistema unix-like un analogo elenco viene mantenuto nel file
-\conffile{/etc/services}, con la corrispondenza fra i vari numeri di porta ed
-il nome simbolico del servizio. I numeri sono divisi in tre intervalli:
+\url{http://www.iana.org/assignments/port-numbers}); inoltre in un sistema
+unix-like un analogo elenco viene mantenuto nel file \conffile{/etc/services},
+con la corrispondenza fra i vari numeri di porta ed il nome simbolico del
+servizio. I numeri sono divisi in tre intervalli:
\begin{enumerate*}
\item \textsl{le porte note}. I numeri da 0 a 1023. Queste sono controllate e
che solo l'amministratore possa allocare queste porte per far partire i
relativi servizi.
-Le \textsl{glibc} definiscono (in \texttt{netinet/in.h})
+Le \textsl{glibc} definiscono in \headfile{netinet/in.h}
\const{IPPORT\_RESERVED} e \const{IPPORT\_USERRESERVED}, in cui la prima (che
vale 1024) indica il limite superiore delle porte riservate, e la seconda (che
vale 5000) il limite inferiore delle porte a disposizione degli utenti. La
associati alle interfacce locali. La notazione \texttt{0.0.0.0} usata da
\cmd{netstat} è equivalente all'asterisco utilizzato per il numero di porta,
indica il valore generico, e corrisponde al valore \const{INADDR\_ANY}
-definito in \file{arpa/inet.h} (vedi \ref{tab:TCP_ipv4_addr}).
+definito in \headfile{arpa/inet.h} (vedi \ref{tab:TCP_ipv4_addr}).
Inoltre si noti come la porta e l'indirizzo di ogni eventuale connessione
esterna non sono specificati; in questo caso la \textit{socket pair} associata
con una struttura, perché il linguaggio C non consente l'uso di una struttura
costante come operando a destra in una assegnazione.
-Per questo motivo nell'header \file{netinet/in.h} è definita una variabile
+Per questo motivo nell'header \headfile{netinet/in.h} è definita una variabile
\macro{in6addr\_any} (dichiarata come \direct{extern}, ed inizializzata dal
sistema al valore \const{IN6ADRR\_ANY\_INIT}) che permette di effettuare una
assegnazione del tipo: \includecodesnip{listati/serv_addr_sin6_addr.c} in
secondi per un numero di volte che può essere stabilito dall'utente. Questo
può essere fatto a livello globale con una opportuna
\func{sysctl},\footnote{o più semplicemente scrivendo il valore voluto in
- \procfile{/proc/sys/net/ipv4/tcp\_syn\_retries}, vedi
+ \sysctlfile{net/ipv4/tcp\_syn\_retries}, vedi
sez.~\ref{sec:sock_ipv4_sysctl}.} e a livello di singolo socket con
l'opzione \const{TCP\_SYNCNT} (vedi sez.~\ref{sec:sock_tcp_udp_options}). Il
valore predefinito per la ripetizione dell'invio è di 5 volte, che comporta
della coda delle connessioni incomplete può essere ancora controllata usando
la funzione \func{sysctl} con il parametro \const{NET\_TCP\_MAX\_SYN\_BACKLOG}
o scrivendola direttamente in
-\procfile{/proc/sys/net/ipv4/tcp\_max\_syn\_backlog}. Quando si attiva la
+\sysctlfile{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 \procfile{/proc/sys/net/ipv4/tcp\_syncookies}) questo valore
+attivare usando \sysctlfile{net/ipv4/tcp\_syncookies}) questo valore
viene ignorato e non esiste più un valore massimo. In ogni caso in Linux il
valore di \param{backlog} viene troncato ad un massimo di \const{SOMAXCONN} se
è superiore a detta costante (che di default vale 128).\footnote{il valore di
Un'altra differenza con BSD è che la funzione non fa ereditare al nuovo socket
i flag del socket originale, come \const{O\_NONBLOCK},\footnote{ed in generale
tutti quelli che si possono impostare con \func{fcntl}, vedi
- sez.~\ref{sec:file_fcntl}.} che devono essere rispecificati ogni volta. Tutto
-questo deve essere tenuto in conto se si devono scrivere programmi portabili.
+ sez.~\ref{sec:file_fcntl_ioctl}.} che devono essere rispecificati ogni
+volta. Tutto questo deve essere tenuto in conto se si devono scrivere
+programmi portabili.
Il meccanismo di funzionamento di \func{accept} è essenziale per capire il
funzionamento di un server: in generale infatti c'è sempre un solo socket in
\subsection{La funzione \func{close}}
\label{sec:TCP_func_close}
-La funzione standard Unix \func{close} (vedi sez.~\ref{sec:file_close}) che si
-usa sui file può essere usata con lo stesso effetto anche sui file descriptor
-associati ad un socket.
+La funzione standard Unix \func{close} (vedi sez.~\ref{sec:file_open_close})
+che si usa sui file può essere usata con lo stesso effetto anche sui file
+descriptor associati ad un socket.
L'azione di questa funzione quando applicata a socket è di marcarlo come
chiuso e ritornare immediatamente al processo. Una volta chiamata il socket
di riferimenti, per cui se più di un processo ha lo stesso socket aperto
l'emissione del FIN e la sequenza di chiusura di TCP non viene innescata
fintanto che il numero di riferimenti non si annulla, questo si applica, come
-visto in sez.~\ref{sec:file_sharing}, sia ai file descriptor duplicati che a
-quelli ereditati dagli eventuali processi figli, ed è il comportamento che ci
-si aspetta in una qualunque applicazione client/server.
+visto in sez.~\ref{sec:file_shared_access}, sia ai file descriptor duplicati
+che a quelli ereditati dagli eventuali processi figli, ed è il comportamento
+che ci si aspetta in una qualunque applicazione client/server.
Per attivare immediatamente l'emissione del FIN e la sequenza di chiusura
descritta in sez.~\ref{sec:TCP_conn_term}, si può invece usare la funzione
caso di Linux anche dall'impostazione di alcuni dei parametri di sistema che
si trovano in \file{/proc/sys/net/ipv4}, che ne controllano il comportamento:
in questo caso in particolare da
-\procrelfile{/proc/sys/net/ipv4}{tcp\_retries2} (vedi
+\sysctlrelfile{net/ipv4}{tcp\_retries2} (vedi
sez.~\ref{sec:sock_ipv4_sysctl}). Questo parametro infatti specifica il numero
di volte che deve essere ritentata la ritrasmissione di un pacchetto nel mezzo
di una connessione prima di riportare un errore di timeout. Il valore
una macchina remota occorre un certo tempo perché i pacchetti vi arrivino,
vengano processati, e poi tornino indietro. Considerando trascurabile il tempo
di processo, questo tempo è quello impiegato nella trasmissione via rete, che
-viene detto RTT (dalla denominazione inglese \itindex{Round~Trip~Time}
+viene detto RTT (dalla denominazione inglese \itindex{Round~Trip~Time~(RTT)}
\textit{Round Trip Time}) ed è quello che viene stimato con l'uso del comando
\cmd{ping}.
attivi.
Per far questo si usa la caratteristica dei file descriptor, descritta in
-sez.~\ref{sec:file_open}, per cui il kernel associa sempre ad ogni nuovo file
-il file descriptor con il valore più basso disponibile. Questo fa sì che si
-possa eseguire il ciclo (\texttt{\small 8}) a partire da un valore minimo, che
-sarà sempre quello del socket in ascolto, mantenuto in \var{list\_fd}, fino al
-valore massimo di \var{max\_fd} che dovremo aver cura di tenere aggiornato.
-Dopo di che basterà controllare (\texttt{\small 9}) nella nostra tabella se il
-file descriptor è in uso o meno,\footnote{si tenga presente che benché il
- kernel assegni sempre il primo valore libero, dato che nelle operazioni i
- socket saranno aperti e chiusi in corrispondenza della creazione e
- conclusione delle connessioni, si potranno sempre avere dei \textsl{buchi}
- nella nostra tabella.} e impostare \var{fset} di conseguenza.
+sez.~\ref{sec:file_open_close}, per cui il kernel associa sempre ad ogni nuovo
+file il file descriptor con il valore più basso disponibile. Questo fa sì che
+si possa eseguire il ciclo (\texttt{\small 8}) a partire da un valore minimo,
+che sarà sempre quello del socket in ascolto, mantenuto in \var{list\_fd},
+fino al valore massimo di \var{max\_fd} che dovremo aver cura di tenere
+aggiornato. Dopo di che basterà controllare (\texttt{\small 9}) nella nostra
+tabella se il file descriptor è in uso o meno,\footnote{si tenga presente che
+ benché il kernel assegni sempre il primo valore libero, dato che nelle
+ operazioni i socket saranno aperti e chiusi in corrispondenza della
+ creazione e conclusione delle connessioni, si potranno sempre avere dei
+ \textsl{buchi} nella nostra tabella.} e impostare \var{fset} di conseguenza.
Una volta inizializzato con i socket aperti il nostro \textit{file descriptor
set} potremo chiamare \func{select} per fargli osservare lo stato degli
-\subsection{I/O multiplexing con \func{epoll}}
+\subsection{I/O multiplexing con \textit{epoll}}
\label{sec:TCP_serv_epoll}
Da fare.