Internet: architettura e protocolli/Application Layer

Indice del libro

Il socket di un processo applicativo è il canale di comunicazione con il livello trasporto: il processo applicativo di un host e il processo applicativo di un altro host si scambiano messaggi attraverso i loro socket.

La comunicazione tra due host può avvenire secondo il paradigma client-server o in maniera peer-to-peer (P2P).

Le applicazioni possono avere diverse esigenze a seconda della loro funzione:

  • integrità dei dati: un'e-mail deve arrivare intera, mentre una telefonata può tollerare la perdita di qualche campione;
  • ritardi: una telefonata è molto sensibile ai ritardi nella conversazione;
  • throughput: le applicazioni multimediali non funzionano se la rete è troppo carica, mentre le applicazioni elastiche come il caricamento di una pagina Web sono in grado di adattarsi al throughput corrente della rete;
  • sicurezza: il protocollo SSL fornisce una connessione TCP criptata per motivi di sicurezza.

Le applicazioni usano vari protocolli di livello applicazione: SMTP per la posta elettronica, HTTP per le pagine Web, ecc.

Protocollo HTTP

modifica

Il protocollo HTTP serve per il recupero di pagine Web dal server. Utilizza il TCP (tipicamente sulla well-known port 80) perché non sono ammesse perdite di pacchetti.

Persistenza

modifica

La versione 1.0 di HTTP è di tipo non persistente: viene aperta una connessione TCP per ogni oggetto (immagini) che costituisce la pagina Web.

 

La ricezione di ogni oggetto richiede l'attesa di 2 RTT + il tempo di trasmissione del file:

  1. viene aperta la connessione TCP tramite three-way handshake;
  2. viene trasferito l'oggetto richiesto dal client.

La versione 1.1 di HTTP è di tipo persistente: tutti gli oggetti della pagina Web vengono scaricati entro un'unica connessione TCP → risparmio di tempo.

Messaggi HTTP

modifica
Messaggi di richiesta

Il client invia dei messaggi di richiesta, nella cui intestazione specifica alcuni campi ASCII tra cui il tipo di comando:

  • GET: richiesta di un oggetto, ad esempio:
    GET /index.html HTTP/1.1
  • POST: invio di input da form, contenuto nel corpo del messaggio;
  • HEAD: uguale a GET, ma il server invia nel messaggio di risposta solo l'intestazione e non il contenuto dell'oggetto;
  • PUT: invio di un file nel corpo del messaggio (solo HTTP/1.1);
  • DELETE: eliminazione di un file (solo HTTP/1.1).

L'intestazione contiene anche il campo Connection:

  • nell'HTTP non persistente il valore predefinito è Close, perché bisogna chiudere la connessione TCP corrente prima di richiedere l'oggetto successivo;
  • nell'HTTP persistente il valore predefinito è Keep-Alive, perché la connessione va chiusa solo dopo che è stato ricevuto l'ultimo oggetto.
Messaggi di risposta

Il server invia dei messaggi di risposta, nella cui intestazione specifica alcuni campi ASCII tra cui il codice di stato:

  • 200 OK: la richiesta è stata completata con successo, ad esempio:
    HTTP/1.1 200 OK
  • 301 Mover Permanently: l'oggetto richiesto è stato spostato in una nuova posizione;
  • 400 Bad Request: il formato del messaggio non è stato riconosciuto;
  • 404 Not Found: l'oggetto richiesto non è stato trovato;
  • 505 HTTP Version Not Supported: la versione HTTP non è supportata.

L'HTTP è stateless: il server non conserva alcuna informazione relativa alle passate richieste da parte del client.

Un cookie è una stringa di testo salvato dal browser sull'host client che contiene alcune informazioni relative alla sessione utente (nome utente, lingua personalizzata), in modo che a ogni successiva visita alla stessa sezione del web il client la rimandi al server e quest'ultimo possa ricordare le operazioni svolte in passato dall'utente senza dover ricominciare da zero.

Server proxy

modifica

Il traffico di una rete locale può passare attraverso un server proxy,[1] che è dotato di una cache in cui salvare le ultime risposte HTTP avvenute → si riduce il tempo di risposta nel caso in cui più client collegati al server proxy richiedano lo stesso oggetto, evitando di sovraccaricare il server di origine. Il server proxy, prima di consegnare la copia in cache al client, verifica con una richiesta HEAD al server di origine che l'oggetto non sia stato modificato nel frattempo: l'intestazione del messaggio di risposta contiene il campo Last-Modified, che informa sulla data di ultimo aggiornamento dell'oggetto. Anche il browser dell'utente può avere una cache locale.

Protocollo FTP

modifica

Il protocollo FTP è ottimizzato per il trasferimento di file. Usa il TCP. L'host lato server non deve essere una macchina attrezzata appositamente a fare da server, ma può essere una macchina qualunque.

Al contrario dell'HTTP, l'FTP è out of band: esiste una connessione dedicata alle informazioni di controllo, e il trasferimento di ogni file richiede l'apertura e la chiusura di una connessione TCP separata dalla connessione di controllo.

Anche nell'FTP i comandi e le risposte sono di tipo ASCII. Tra i comandi:

  • LIST restituisce l'elenco dei file nel direttorio corrente;
  • RETR nome_file: recupera un file;
  • STOR nome_file: archivia un file in un host remoto.

Posta elettronica

modifica
  1. l'utente mittente contatta il suo server di posta e gli invia l'e-mail;
  2. l'e-mail, salvata nella mailbox del server mittente, entra in una coda[2] di messaggi da inviare non appena il server mittente riesce a contattare il server destinatario;
  3. l'e-mail viene ricevuta dal server destinatario e salvata nella mailbox del server;
  4. quando l'utente destinatario accederà alla posta troverà l'e-mail.

Protocollo SMTP

modifica

Il protocollo SMTP serve per l'invio di posta elettronica al server di posta. Utilizza il TCP (tipicamente sulla well-known port 25).

Un relay mail server è un server di posta configurato per accettare la posta proveniente da qualsiasi indirizzo IP, in modo che l'utente titolare dell'account di posta possa accedere alla propria posta da qualsiasi postazione Internet. L'RFC del protocollo SMTP tuttavia sconsiglia i relay server come misura anti-spam; inoltre il contenuto del comando HELO viene spesso confrontato con una blacklist.

Esempio di conversazione

modifica

I server comunicano tra di loro tramite comandi e risposte testuali ASCII (caratteri ASCI a 7 bit) → vantaggioso per il debug, ma svantaggioso per lo spreco di byte.

# Handshaking (presentazione)
C:  <apre la connessione>
S:  220 nome_server_B   # la conversazione inizia sempre con il codice 220
C:  HELO nome_server_A   # comunica il proprio nome
S:  250   # il nome è stato ricevuto
C:  MAIL FROM: <indirizzo_email_mittente>
S:  250   # conferma del mittente
C:  RCPT TO: <indirizzo_email_destinatario>
S:  250   # conferma del destinatario
# Trasferimento del messaggio
C:  DATA   # voglio iniziare a scrivere il messaggio
S:  354   # scrivi pure
C:  To: indirizzo_email_destinatario
C:  From: indirizzo_email_mittente
C:  Subject: oggetto_messaggio
C:  # una riga vuota, e più precisamente il carattere CRLF, separa l'intestazione dal corpo del messaggio
C:  corpo_messaggio
C:  .   # il punto sta a significare la fine del messaggio
S:  250   # messaggio accettato
# Chiusura della sessione
C:  QUIT   # voglio chiudere la connessione
S:  221
C:  <chiude la connessione>

Si noti che, poiché le informazioni inviate nella fase di handshaking non vengono mantenute, l'indirizzo del mittente e quello del destinatario vengono riportati anche nel testo stesso del messaggio.

Allegati

modifica

L'RFC originale del protocollo SMTP prevedeva solamente lo scambio di testo. L'evoluzione di questo RFC permette anche lo scambio di file grazie al MIME, cioè delle righe aggiuntive nell'intestazione del messaggio che dichiarano il tipo di contenuto MIME del file.

Esempio: invio di un'immagine JPEG
...
C:  To: indirizzo_email_destinatario
C:  From: indirizzo_email_mittente
C:  Subject: oggetto_messaggio
C:  MIME-Version: 1.0
C:  Content-Transfer-Encoding: base64
C:  Content-Type: image/jpeg
C:  
C:  bit_immagine   # corpo del messaggio
...

Protocollo POP3

modifica

Il protocollo POP3 serve per il recupero della posta elettronica dal server di posta. Usa il TCP.

Il protocollo IMAP migliora il protocollo POP3, che è stateless.

Esempio di conversazione

modifica
Ipotesi
  • ci sono 2 messaggi di posta non letti sul server;
  • non si utilizza il protocollo di sicurezza SSL.
# Autorizzazione
C:  <apre la connessione>
S:  +OK   # server POP3 pronto
C:  user nome_utente
S:  +OK   # il server può rispondere +OK o −ERR
C:  pass password   # la password è in chiaro → serve l'SSL
S:  +OK   # accesso con successo
# Transazione
C:  list   # quanti nuovi messaggi?
S:  1 498
S:  2 912
...
S:  .   # messaggi finiti
C:  retr 1   # chiede il contenuto del primo messaggio
S:  contenuto_messaggio
S:  .   # il contenuto del messaggio è terminato
C:  dele 1   # ordina di eliminare il messaggio dal server
C:  retr 2   # chiede il contenuto del secondo messaggio
S:  contenuto_messaggio
S:  .   # il contenuto del messaggio è terminato
C:  dele 2   # ordina di eliminare il messaggio dal server
# Chiusura della sessione
C:  quit   # voglio chiudere la connessione
S:  +OK
C:  <chiude la connessione>

Il comportamento predefinito del client di posta, previsto dall'RFC del POP3, è quello di ordinare l'eliminazione del messaggio subito dopo averlo ricevuto dal server; l'utente può configurare il proprio client di posta affinché il messaggio sia mantenuto sul server.

Reti P2P

modifica

Nelle reti P2P non esiste un server sempre acceso al quale tutti si collegano per ricevere i file: i nodi di una rete P2P, chiamati peer, fungono sia da client sia da server, e sono connessi in modo intermittente.

Più peer stanno condividendo un file, più le prestazioni di distribuzione migliorano, perché un peer mentre sta scaricando il file può nel frattempo condividere la parte scaricata con un altro peer, mentre nel mondo client-server la banda dell'unico server è limitata:

 

Protocollo BitTorrent

modifica

I file sono suddivisi in parti (chunk) da 256 KB. Il torrent è il gruppo di peer che sta condividendo i chunk di un file; la rete P2P è chiamata rete overlay. Il tracker è il server che gestisce la distribuzione di un certo file tra i peer. Un host si collega periodicamente al tracker, il cui indirizzo è specificato in un file .torrent, e il tracker fornisce all'host una lista composta da un numero massimo di indirizzi IP di peer a cui l'host potrà collegarsi per recuperare il file.

Tra i peer si distinguono i seed, cioè gli host che possiedono l'intero file. I seed possono altruisticamente rimanere collegati alla rete oppure egoisticamente abbandonarla: il churn, cioè il tasso di abbandono, influisce molto sulle prestazioni della rete.

L'host può scambiare i chunk del file con i peer che il tracker gli ha comunicato.

Richiesta di chunk

L'host chiede periodicamente a ogni peer una lista dei chunk che possiedono, quindi applica un algoritmo local rarest first: richiede il chuck mancante più raro nel vicinato, cioè quello che è posseduto da meno peer.

Invio di chunk

Tra quelli che stanno richiedendo chunk, periodicamente l'host sceglie (choke) i 4 peer da cui è riuscito a scaricare a una velocità più alta nel passato, e inizia a mandare loro dei chunk. Questo meccanismo, chiamato tit-for-tat, serve per svantaggiare i freerider, cioè gli host che scaricano senza condividere. Per evitare di contattare sempre gli stessi peer, si applica l'optimistically unchoke: ogni 30 secondi l'host sceglie in modo casuale un altro peer e inizia a inviargli dei chunk, con la speranza di essere in futuro scelto da quel peer in modo da poter ricevere dei chunk che i soliti peer non hanno.

Napster, la prima rete P2P, era costituito da un unico tracker che serviva l'intera rete → scollegando il server fu facile smantellare la rete per motivi legali. Le reti P2P si stanno sempre più orientando verso il DHT: il database P2P, anziché essere concentrato in singoli tracker, è distribuito tra i peer stessi. Il database è organizzato per coppie (chiave, valore) (ad esempio chiave = titolo del film, valore = indirizzo IP). Un peer può interrogare il database distribuito facendo una ricerca per chiave, e può anche inserire una coppia (chiave, valore).

Le coppie (chiave, valore) vengono assegnate ai peer tramite una tabella di hash:

  1. ogni chiave viene convertita in un id intero da una funzione di hash;
  2. ad ogni peer viene assegnato un id intero (per esempio una funzione di hash converte l'indirizzo IP del peer);
  3. la coppia viene assegnata al peer il cui id è pari o, nel caso non sia esistente, immediatamente successivo all'id della chiave; se viene superato il massimo id presente nella rete, la coppia viene assegnata al peer di id più basso.

Una rete P2P con DHT è strutturata, cioè il grafo della rete non è costruito in modo casuale.

La rete Chord ha una topologia circolare: ogni peer, oltre a conoscere il proprio id, conosce solo gli indirizzi IP del suo immediato precedessore e del suo immediato successore → la ricerca di una chiave percorre la catena di peer fino ad arrivare al peer il cui id è pari o immediatamente successivo all'id della chiave cercata.

La complessità di questo meccanismo di ricerca è alta ( O(n) ) rispetto al sistema con il tracker ( O(1) ).

Grazie ai shortcut, cioè delle "scorciatoie" verso i peer distanti un numero di hop potenza del 2, le prestazioni migliorano a O(logn).

Kademlia

modifica

La rete Kademlia di eMule è invece basata su una topologia ad albero binario: ha prestazioni O(logn) senza dover ricorrere a shortcut.

  1. L'utente deve specificare manualmente al browser l'indirizzo del server proxy.
  2. Non è una vera e propria coda.