# UDP hole punching

L' UDP hole punching est une technique communément utilisée dans les systèmes utilisant un système de translation d'adresses (NAT) afin de faire communiquer, par UDP (User Datagram Protocol), deux machines se trouvant sur des réseaux privés différents.
Cette technique est communément utilisée dans les logiciels peer-to-peer et la téléphonie sur IP (Voice over Internet Protocol). Elle peut également être utilisée pour permettre l'établissement d'un réseau privé virtuel sur UDP.
L'UDP hole punching établit la connectivité entre deux hôtes communiquant à travers un ou plusieurs traducteurs d'adresses. Généralement, un hôte tiers présent sur le réseau public est utilisé pour établir les numéros de ports réseau qui seront utilisés pour une communication directe entre les hôtes privés.
Une fois que la communication a été établie, l'état des serveurs NAT est maintenu par un trafic de communication normal, ou en absence d'un tel trafic, par des paquets keep-alive (consistant généralement en paquets UDP vides ou en paquets ayant un contenu minimal).

## Fonctionnement

L'UDP hole punching est une méthode pour établir une communication UDP bidirectionnelle, à travers Internet, entre deux hôtes situés dans des réseaux privés. Cette technique n'est pas applicable dans tous les scénarios ou avec tous les types de NAT.

### Rappel sur le NAT

Plusieurs types de NAT existent. Dans l'explication suivante nous prendrons comme cas le NAT dynamique masquerading.
Le NAT permet aux machines d'un réseau privé d'établir des connexions sortantes vers Internet avec une seule adresse IP publique, l'adresse de la machine NAT. Pour ce faire le NAT va maintenir un suivi des connexions démarrées par les machines du réseau privé et au tuple d'adresses IP et de port réseau, source puis destination, (IP$_1$, P$_1$, IP$_{dst}$, P$_{dst}$) va faire correspondre le tuple (EIP, EP$_X$, IP$_{dst}$, P$_{dst}$).
Lorsque la machine contactée va répondre elle répondra avec le tuple (IP$_{dst}$, P$_{dst}$, EIP, P$_X$).
Pour faire communiquer deux machines, M$_1$ et M$_{alpha}$, de réseaux privés différents il suffit donc :
* que M$_1$ connaisse l'adresse publique de M$_{alpha}$ et le port Y utilisé par le NAT$_B$
* et que M$_{alpha}$ connaisse l'adresse publique de M$_1$ et le port X utilisé par NAT$_A$.
Au passage du premier paquet UDP de M$_1$ vers M$_{alpha}$ le NAT$_A$ enregistrera dans ses connexions ouvertes le fait qu'il attend un retour.
Au passage du premier paquet UDP de M$_{alpha}$ vers M$_1$ à travers le NAT$_B$, ce dernier enregistrera cette connexion comme en cours d'ouverture et attendra un retour.
À ce point là les NAT/Firewall auront été poinçonnés (traduction littérale de Hole Punching) et permettront donc le dialogue entre M$_1$ et M$_{alpha}$
Il est à noter que même si le terme de Hole Punching peut faire penser à un trou dans le Firewall cette technique ne remet pas en cause la sécurité du NAT/Firewall.
Les machines M$_1$ et M$_{alpha}$ doivent donc trouver un moyen de s'échanger ces informations.

### Echanges d'information

Les hôtes se trouvant sur réseau privé et accédant à Internet par un NAT utilisent généralement la méthode STUN (Session Traversal Utilities for NAT) ou ICE (Interactive Connectivity Establishment (en)) pour déterminer l'adresse publique du serveur NAT de l'autre bout de la communication.
Dans le processus d'UDP Hole punching on utilise un serveur de rendez-vous S, sur le réseau public, pour échanger les informations nécessaires à la communication directe entre les deux pairs.
Les deux hôtes commencent à émettre, et utilisent plusieurs tentatives. Sur un Restricted cone NAT (en), le premier paquet de l'hôte distant sera bloqué.
Le NAT enregistre ensuite le fait qu'il y ait eu l'envoi d'un premier paquet vers l'hôte distant et permettra la réception de tout paquet ayant l'adresse IP et le port de l'hôte distant.

### Maintien de connexion

Sur un serveur NAT, l'état d'une communication UDP expire après une certaine période, quelques dizaines de secondes généralement, le UDP hole punching ré-envoie donc périodiquement des paquets keep-alive pour s'assurer de la mise à jour des compteurs de la machine d'état du NAT et ainsi l'empêcher de clore la communication.

### Limitations

L'UDP hole punching ne marche pas avec machines faisant du symmetric NAT (en) (aussi appelé NAT bi-directionnel) qui se retrouve fréquemment dans les réseaux de grosses entreprises.
Le Firewall du serveur NAT doit rejeter l'ouverture de connexion depuis l'extérieur sinon ce premier flux prendra le port prévu et les flux sortant du NAT en provenance de la Machine privée seront contraint de prendre un port différent, cassant le mécanisme de Hole Punching.

## Etapes de la mise en place du Hole Punching

Soient M$_1$ et M$_{alpha}$, deux hôtes, chacun sur son propre réseau privé;
Soient NAT$_A$ et NAT$_B$ les deux routeurs NAT avec des adresses publiques respectives EIP$_A$ et EIP$_B$;
Soit S est un serveur public avec une adresse IP publique connue.
* 1. M$_1$ et M$_{alpha}$ commencent chacun un échange UDP avec S; les serveurs NAT$_A$ et NAT$_B$ créent leurs états de translation UDP et assignent un numéro de port externe temporaire, EP$_A$ et EP$_B$.
* 2. S examine les paquets UDP pour connaitre les ports source utilisés par NAT$_A$ et NAT$_B$ (les ports NAT externes EP$_A$ et EP$_B$).
* 3. S communique EIP$_A$:EP$_A$ à M$_{alpha}$ et EIP$_B$:EP$_B$ à M$_1$.
* 4. M$_1$ envoie un paquet à EIP$_B$:EP$_B$.
* 5. NAT$_A$ examine le paquet de M$_1$ et créé le couple de tuple suivant dans sa table de translation: (IP$_1$, P$_1$, EIP$_B$, EP$_B$)=>(EIP$_A$, EP$_A$, EIP$_B$, EP$_B$).
* 6. M$_{alpha}$ envoie un paquet à EIP$_A$:EP$_A$.
* 7. NAT$_B$ examine le paquet de M$_{alpha}$ et créé le couple de tuples suivant dans sa table de translation: (IP$_{alpha}$, P$_{alpha}$, EIP$_A$, EP$_A$)=>(EIP$_B$, EP$_B$, EIP$_A$, EP$_A$).
* 8. Selon l'état de la table de translation de NAT$_A$ lorsque le premier paquet de M$_{alpha}$ arrive, ce paquet est éliminé (s'il n'y a pas d'entrée dans la table de translation) ou accepté (si une entrée existe).
* 9. Selon l'état de la table de translation de NAT$_B$ lorsque le premier paquet de M$_1$ arrive, ce paquet est éliminé (s'il n'y a pas d'entrée dans la table de translation) ou accepté (si une entrée existe).
* 10. Ainsi, des trous ont été créés dans les NAT, les deux hôtes peuvent communiquer directement. Dans le pire des cas, le second paquet de M$_1$ atteint M$_{alpha}$ et le second paquet de M$_{alpha}$ atteint M$_1$.
Si les deux hôtes ont un Restricted cone NAT (en) ou un Symmetric NAT (en), les ports externes du NAT vont différer de ceux utilisés pour S. Sur certains routeurs, les ports externes sont choisis séquentiellement, rendant ainsi possible l'établissement d'une conversation en devinant les ports choisis.

## Voir également

* ICMP hole punching (en)
* TCP hole punching (en)
* Hole punching (networking) (en)
* WebRTC
* Port Control Protocol (en) (PCP)