Pagine    Articoli    Prodotti    Forum    Cerca  
Nickname

Password


Non sei registrato?
Registrati a GPI qui!

Puoi anche attivare un vecchio utente GPI e chiedere una nuova password.
I Team

Mappa Team
I nostri utenti

Mappa Utenti
  NAT e NAT Facilitation
Pubblicato da Davide Barbieri il 2013-10-11 08:53:29

Introduzione

Una partita multiplayer si configura molto spesso come un sistema distribuito di tipo client-server.
In questa architettura il server ha il compito di guidare la simulazione (i.e. la successione degli eventi di gioco), preoccupandosi di ricevere ed integrare gli input (nel senso più ampio del termine) dei client e di inviare agli stessi gli aggiornamenti che riassumono i cambiamenti tra lo stato attuale della simulazione e quello relativo all'ultimo aggiornamento ricevuto.
Questo scambio di informazioni tra client e server permette, se ben orchestrato, di ottenere la stessa simulazione (o una sua approssimazione accettabile) su tutti i computer dei partecipanti al gioco.

Nella maggior parte dei casi il server viene ospitato su un computer (dedicato o virtuale) configurato dallo sviluppatore, o da chi offre a lui questo servizio.
Alcune volte invece lo stesso compito è affidato al computer di uno dei giocatori, permettendo allo stesso giocatore di configurare alcuni parametri della partita ed avere un controllo maggiore sul tipo di match che verrà disputato.

 

Agli albori di Internet ogni interfaccia di rete connessa aveva un indirizzo IP unico che poteva essere utilizzato per ricevere pacchetti da qualsiasi altro computer della rete. Per cui, era sempre possibile connettersi ad un server dedicato o ad un server ospitato da un altro utente.

Attualmente, invece, la rete presenta diverse sotto-reti private, come ad esempio quella formata da un router di una rete domestica e dai pc ad esso connessi, le quali riutilizzano nel loro contesto locale un range di indirizzi ip comune a molte altre sottoreti (192.168.*.* vi dice qualcosa?).

 


Con questa topologia, sono necessari diversi espedienti per permettere la comunicazione tra i computer appartenenti a sottoreti differenti di internet. Uno di questi espedienti è il NAT, o Network Address Translation.

Network Address Translation

Il gateway che utilizziamo per connetterci ad internet riceve dall'Internet Service Provider generalmente un solo indirizzo ip pubblico e questo indirizzo viene condiviso da tutti i computer della sottorete come unico punto d'accesso alla rete globale.

Il meccanismo di Network Address Translation viene attuato dal router per permettere ad un qualsiasi computer della sua sottorete (che ha un indirizzo IP unico solo in locale) di connettersi ad un indirizzo esterno, e di ricevere i dati di risposta provenienti da esso.

Il funzionamento, in linea di massima, è il seguente:

  • - il computer invia un pacchetto (su cui è scritto l'ip destinatario) al router che gli fa da gateway (e.g. 192.168.0.1);
  • - il router si segna l'interfaccia di rete da cui proviene il pacchetto (e.g. 192.168.0.2), genera un numero di porta ancora inutilizzato (e.g. 1512) e salva la corrispondenza ip:porta (e.g. 1512 -> 192.168.0.2) nella tabella di NAT
  • - il router modifica il pacchetto IP scrivendo come mittente il proprio indirizzo ip pubblico (quello fornito dal service provider di internet) e come porta mittente la porta appena generata.
  • - il router instrada il pacchetto verso la rete 
  • - il destinatario riceve il pacchetto dalla rete e risponde al pacchetto (i.e. utilizzando come destinazione la coppia ip:porta mittente modificata dal router);
  • - il router riceve la risposta, controlla la porta destinataria e cerca nella tabella di NAT l'indirizzo Ip della rete interna su cui era mappata quella porta
  • - il router invia il pacchetto all'indirizzo ritrovato (e.g. 192.168.0.2), preoccupandosi di ripristinare nel pacchetto l'indirizzo ip destinatario corretto.

 


Questo meccanismo è completamente automatico e trasparente, e permette ad un qualsiasi computer di fare da client in una partita multiplayer in rete.

Per poter permettere agli utenti del proprio videogioco di fare da host (server) di una partita, d'altro canto, questo meccanismo non è sufficiente. Un qualsiasi tentativo di connessione spontaneo che arriva all'indirizzo IP di un gateway,
infatti, resta irrisolto se il router non sa qual è l'indirizzo ip della sottorete che dovrà ricevere la richiesta.

Esistono vari modi per ovviare a questo problema:

  • - Port forwarding. Qualsiasi router fornisce un'interfaccia web che permette di associare in modo manuale una porta ad un particolare indirizzo IP della sottorete. Anche essendo una procedura piuttosto facile per lo smanettone medio (e la diffusione di programmi come Emule ha aiutato molto), molti utenti non hanno la capacità/voglia di effettuare questo tipo di operazione;
  • - Esiste una classe di protocolli, chiamata uPnP, supportata ormai dalla stragrande maggioranza dei router, che permette ad un qualsiasi programma di ricercare in rete il router di casa ed effettuare automaticamente la configurazione del port forwarding.
    Spesso, però, questa funzionalità deve essere prima abilitata da interfaccia web e non è affidabile al 100% a causa delle differenti implementazioni da parte dei router.

 

Queste due soluzioni permettono, però, di risolvere il problema soltanto nel caso in cui il vostro gateway interfacci la vostra sottorete direttamente ad Internet. Non è sempre questo il caso. Alcuni provider, e.g. Fastweb, forniscono al router un IP (o un insieme di IP forniti direttamente alle macchine ad esso connesse) che non sono pubblici, ma appartenenti ad una sotto rete
più grande. I computer della sottorete non possono essere contattati direttamente dall'esterno, per questo motivo alcune reti P2P (e.g. Emule Adunanza) nascono e funzionano solo all'interno di una di queste reti.
In questo caso il NAT per le vostre connessioni è effettuato autonomamente da un router remoto presente nella rete del provider, e dunque il port forward non puo' essere configurato dall'utente ne' manualmente ne' tramite uPnP.

  • - Con IPv6, la prossima versione del protocollo utilizzato per i pacchetti Internet, questo problema dovrebbe sparire. L'intenzione è infatti quella di assegnare un indirizzo ip unico ad ogni interfaccia di rete del mondo connessa in rete (essendo un indirizzo a 128 bit, la disponibilità sarà di circa 650 mila miliardi di miliardi di indirizzi per metro quadro di superficie terrestre). In questo scenario, anche il NAT stesso non sarà più necessario.
  • - In attesa che IPv6 venga effettivamente adottato da tutti, la soluzione temporanea universalmente adottata è quella della tecnica del NAT punch-through, nonostante anch'essa non sia completamente affidabile (a causa, questa volta, delle diverse implementazioni dell'algoritmo di NAT utilizzate dai router).

NAT punch-through

Il NAT punch-through è una tecnica che permette ad un computer interfacciato alla rete tramite NAT, di essere comunque
contattato da un computer esterno. Esso si basa sulla presenza di un processo, chiamato NAT Facilitator (o Introducer), che viene eseguito su un computer il cui indirizzo IP è raggiungibile globalmente (ad esempio, un processo presente su un server dedicato) e a cui sia l'host che i client si connettono.
Ogni volta che un client vuole connettersi ad un server dietro NAT, contatta il NAT Facilitator e richiede di "facilitare" questa connessione.
Il Facilitator, dunque, avverte l'host di questa intenzione ed invia ad entrambi l'indirizzo ip dell'altro e quale porta l'altro ha utilizzato per connettersi al Facilitator.

Da questo momento in poi, sia il server che il client conoscono l'indirizzo IP dell'altro (ed una porta generata dal NAT remoto), e, per poter finalmente instaurare una connessione (intesa come un canale che permette ad entrambi di scambiarsi messaggi), eseguono un algoritmo, detto NAT Traversal, che "forza" il funzionamento del NAT per fare una cosa
per cui non era stato inizialmente pensato: ricevere messaggi da un computer non precedentemente contattato (in altre parole, per cui non è stata generata una corrispondenza all'interno della tabella di NAT).
Da notare che, una volta creato il canale di comunicazione, i messaggi inerenti al videogioco verranno scambiati direttamente tra le due parti, senza dover passare per il NAT Facilitator.

Come è possibile intuire, essendo questo uno stratagemma che forza un funzionamento non inizialmente previsto, le possibilità che esso funzioni dipendono della particolare implementazione dell'algoritmo di NAT utilizzato dal router.
In particolare, molti router permettono il NAT traversal per una comunicazione con protocollo di trasporto UDP (che descriviamo qui), molti di meno per messaggi TCP (che è più complesso).
A titolo informativo, Unity3D si appoggia alla libreria RakNet per il networking, e dunque basa tutta la sua comunicazione su pacchetti UDP (anche per la gestione della comunicazione affidabile), ciò fa sì che esso necessiti di NAT Traversal soltanto per pacchetti UDP,
con ovvi benefici sull'affidabilità di questa tecnica.

Algoritmo

Immaginiamo di voler mettere in comunicazione A e B, due peer appartenenti a due sottoreti diverse dietro NAT.
La prima parte dell'algoritmo è già stata descritta nel paragrafo precedente:

  • 1 - A e B instaurano una comunicazione UDP con il Facilitator utilizzando la porta aINT e bINT; i rispettivi NAT generano una porta aEXT e bEXT per queste connessioni.
  • 2 - Il Facilitator esamina i pacchetti UDP di entrambi e legge le due porte mittenti aEXT e bEXT.
  • 3 - Il Facilitator invia l'indirizzo IP esterno di A e la porta aEXT a B, e invia l'indirizzo di B e la porta bEXT ad A.

Dopo che A e B si "conoscono",

  • 4 - A riutilizza la porta aINT precedentemente utilizzata per comunicare al Facilitator e tenta di contattare B su bEXT (se permissivo, il NAT riutilizzerà la stessa porta)
  • 5 - Nello stesso momento, B fa la stessa cosa con A.
  • 6 - Il router di entrambi riceve il pacchetto, il NAT riconosce che esiste un'entry valida nella tabella di NAT (poiché era stata creata nella comunicazione con il Facilitator) e reinstada il pacchetto verso il destinatario corretto.

Diverse implementazioni di NAT

L'algoritmo sopra descritto funziona soltanto se i NAT coinvolti hanno un funzionamento abbastanza permissivo.
Non esiste uno standard per l'algoritmo di NAT, per cui ogni router lo implementa a modo proprio, ma possiamo elencare 4 tipologie di NAT in cui il vostro router può ricadere.

Denotiamo con A, R e B, rispettivamente, l'indirizzo ip del computer all'interno della sottorete, l'indirizzo ip in internet del router e l'indirizzo ip del computer remoto.
Consideriamo questo scenario:

  1. 1 - A invia un pacchetto al router con porta sorgente aINT verso B:bEXT. 
  2. 2 - Il router genera una porta aEXT e mappa la corrispondenza sul NAT, poi invia il pacchetto con mittente R:aEXT e destinatario B:bEXT.
  3. 3 - B riceve il pacchetto e risponde ad R.
  4. 4 - R riceve il pacchetto, controlla che sia tutto a posto e lo reinstrada verso A.

Le differenze tra i NAT insistono sui punti 2 e 4, cioè su cosa segno sul NAT e su che tipo di controllo
faccio per "accettare" i pacchetti.

Full cone NAT

2 - Il router genera una porta aEXT per ogni nuova aINT utilizzata da A. Se A riutilizza aINT per inviare ad host diversi, aEXT viene riutilizzata.
La corrispondenza mappata è dunque semplicemente (aEXT -> A:aINT).
4 - Tutto ciò che arriverà a R:aEXT verrà reinstradato ad A:aINT, qualsiasi sia l'indirizzo mittente (anche diverso da B).

Address-Restricted cone NAT

2 - La corrispondenza è la stessa, ma il router aggiunge B ad una lista degli indirizzi contattati da A.
4 - Tutto ciò che arriverà a R:aEXT verrà inviato ad A:aINT, ma solo se l'indirizzo mittente è presente nella lista sopra descritta
(cioè se A aveva precedentemente inviato all'indirizzo in esame).
Nell'algoritmo di punch-through, in questo caso, il fatto che entrambi i peer si inviano contemporaneamente un messaggio fa sì che
entrambi potranno in seguito ricevere dall'altro peer.

Port-Restricted cone NAT

2 - Come Address-Restricted cone, ma il router include anche la porta bEXT nel record (B:bEXT) da inserire nella lista degli indirizzi contattati.
4 - Come Address-Restricted cone, ma la coppia indirizzo:porta mittente deve essere presente nella lista sopra descritta
(cioè A deve aver precedentemente inviato all'indirizzo in esame, usando la stessa porta in esame).

Symmetric NAT

2 - Il router genera una porta aEXT per ogni nuova aINT utilizzata da A ed ogni destinatario. Se viene inviato un paccheto da A:aINT verso B1:bEXT1,
e poi un pacchetto da A:aINT verso B2:bEXT2 verranno dunque generate 2 porte aEXT1 e aEXT2 per i due destinatari.
La corrispondenza mappata sarà (aEXT1 -> A:aINT [destinatario B1:bEXT1]) e (aEXT2 -> A:aINT [destinatario B2:bEXT2]). La lista degli indirizzi contattati
qui non ha nessuna utilità poiché abbiamo già il massimo della "fiscalità" possibile.
4 - Il router reinstrada da aEXT1 verso A:aINT solo se il mittente è B1:bEXT1, reinstrada da aEXT2 verso A:aINT solo se il mittente è B2:bEXT2.

 

Il NAT punch-through ha sempre successo se almeno uno dei due NAT è di tipo "Full Cone" o "Address-Restricted Cone", oppure nel caso in cui entrambi i NAT siano di tipo "Port-Restricted Cone".
Negli altri due casi (entrambi "Symmetric NAT", oppure un "Symmetric NAT" e un "Port-Restricted Cone") invece le limitazioni sull'uso della porta da utilizzare per la comunicazione e il fatto che viene generata dal router una porta per ogni ip di destinazione (e quindi non può essere riutilizzata la porta esterna utilizzata per comunicare con il Facilitator) implicano che un peer o entrambi debba/debbano "tirare ad indovinare" cercando di prevedere quale sarà la porta generata dal peer che usa Symmetric NAT.
La predizione, semplicemente, può essere quella di provare a connettersi ad un insieme di porte "vicine" a quella utilizzata per il Facilitator (nella speranza che il router remoto le generi in modo sequenziale).

Conclusione

In questo articolo abbiamo visto come client e server, seppur appartenenti a sottoreti diverse, possano dialogare tra di loro grazie a meccanismi come il NAT e il NAT punch-through.
Abbiamo descritto abbastanza in dettaglio l'algoritmo utilizzato per effettuare il punch-through e dove questa tecnica fallisce. Spero che l'articolo sia stato di vostro gradimento!

 

Davide Barbieri

 


I grafici sono stati realizzati tramite: https://www.gliffy.com

 

Bibliografia

[http://it.wikipedia.org/wiki/IPv4]
[http://it.wikipedia.org/wiki/IPv6]
[http://www.jenkinssoftware.com/raknet/manual/natpunchthrough.html]
[http://en.wikipedia.org/wiki/UDP_hole_punching]
[http://www.brynosaurus.com/pub/net/p2pnat/]
[http://docs.unity3d.com/]

Campagne crowfunding

Just One Line
Siamo presenti su

     
Copyright ©2016 - Manifesto - Privacy - Termini di Servizio - Community - Collaboratori - Contattaci