web-dev-qa-db-fra.com

Programmation d'une application P2P

J'écris un programme p2p personnalisé qui s'exécute sur le port 4900. Dans certains cas, lorsque la personne est derrière un routeur, ce port n'est pas accessible depuis Internet.

Existe-t-il un moyen automatique d'activer l'accès au port depuis Internet? Je ne suis pas vraiment sûr du fonctionnement des autres applications p2p.

Quelqu'un peut-il éclairer cela?

38
Jayesh

Connectivité P2P en bref. Supposons que nous parlons d'UDP ici. Les étapes ci-dessous peuvent également être appliquées à TCP avec quelques ajustements.

  1. Énumérer toutes vos adresses IP locales (généralement une seule). Créez un socket UDP sur un numéro de port donné ** pour chaque adaptateur avec une adresse IP.

  2. Pour chaque socket créé à l'étape 1, contactez un serveur STUN ou TURN avec ce même socket pour découvrir votre adresse IP externe et découvrir à quoi correspond le numéro de port interne en dehors de NAT (ce n'est pas toujours la même valeur de port). Autrement dit, votre adresse locale 192.168.1.2:4900 peut être 128.11.12.13:8888 vers le monde extérieur. Et certains NAT n'utilisent pas toujours le même mappage de port lors de l'utilisation du même port local avec d'autres Adresses IP. TURN vous fournira également une "adresse de relais". Vous pouvez également utiliser UPNP pour obtenir une adresse mappée de port directement à partir de votre routeur, s'il prend en charge ce protocole.

  3. Par le biais d'un service de rendez-vous (SIP, XMPP, messagerie instantanée, service Web, e-mail, cups with strings), publiez votre liste de candidats d'adresse à un service ou envoyez une notification à l'autre client qui dit, "hé, je veux me connecter avec vous ". Ce message inclut tous les "candidats d'adresse" (paires ip et ports) collectés aux étapes 1 et 2.

  4. Le client distant, lors de la réception de l'invitation à se connecter, effectue également les étapes 1 et 2 ci-dessus. Renvoie ensuite sa liste de candidats via le même canal sur lequel il a reçu la liste de candidats de l'invitant.

  5. Étape de perforation. Les deux clients commencent à envoyer des messages de test via UDP aux candidats d'adresse de l'autre côté et à écouter les mêmes messages de leur côté. Chaque fois qu'un message est reçu, répondez à l'adresse d'où il provient. Finalement, les clients découvriront qu'ils ont une paire d'adresses qu'ils peuvent également envoyer de manière fiable des datagrammes. En règle générale, un point d'extrémité prend la décision finale sur la paire d'adresses (sockets) avec laquelle communiquer et le protocole facilite ce point d'extrémité en indiquant à l'autre point d'extrémité cette décision.

** - généralement préférable de ne pas compter sur un port bien connu pour les clients P2P. Parce que deux clients derrière le même NAT ou pare-feu ne pourraient probablement pas utiliser votre logiciel en même temps.

Voici un bref résumé de certaines technologies à explorer.

STUN - Est un simple serveur et protocole permettant aux clients derrière un NAT/route de découvrir ce que sont leurs mappages IP et de ports externes.

TURN est une extension de STUN, mais prend en charge le relais pour les scénarios de connectivité P2P où les pare-feu et les NAT empêchent les connexions directes.

ICE est un ensemble d'étapes par lesquelles STUN et TURN sont utilisés pour configurer une connexion P2P. ICE est un protocole formel pour les étapes 1 à 5 ci-dessus. Deux excellentes séries de diapositives sur ICE sont ici et ici .

WebRTC est une variante de la norme ICE ainsi qu'une bibliothèque de référence pour créer des sessions P2P avec STUN et TURN.

PNP + Internet Gateway Device Protocol - Certains routeurs le prennent en charge pour que les hôtes obtiennent automatiquement les mappages de ports.

libnice est une bibliothèque C open source pour Linux (et peut fonctionner sur Windows) qui implémente ICE.

libjingle est une autre implémentation ICE (en C++) de Google. Pour Windows et Linux.

PJNATH est une bibliothèque de la suite PJSIP de bibliothèques de codage. C'est une bonne implémentation d'une pile ICE (code C) et a été portée sur de nombreuses plates-formes. (Windows, Linux, Mac, iOS, Symbian et bientôt Android).

Et enfin, j'ai une prise flagrante à utiliser ma base de code de serveur STUN .

111
selbie

Il existe des solutions dans certains cas, voir UPnP: https://en.wikipedia.org/wiki/Universal_Plug_and_Play#NAT_traversal

Mon routeur domestique permet cela, fondamentalement, le NAT peut être configuré automatiquement par la demande appropriée de l'ordinateur.

Je ne compterais pas sur cela pour fournir une grande amélioration de votre disponibilité, car pas beaucoup de routeurs prennent en charge cela et l'ont activé.

EDIT: @David a suggéré cette SO question pour une bibliothèque .NET pour UPnP: Existe-t-il une bibliothèque UPnP pour .NET (C # ou VB.NET)?

4
jv42

J'utiliserais la technologie WebRTC comme framework open source pour une telle application.

Site officiel

En fait, il s'agit d'un projet open source qui prend en charge tout le nécessaire pour les technologies peer-to-peer prêtes à l'emploi:

  • ICE et STUN (traversée NAT)
  • DTLS et SRTP (sécurité)
  • AVPF pour la qualité du streaming.
3
ankitr

Vous avez une autre option qui est NAT Port Mapping Protocol (NAT-PMP) NAT-PMP est largement utilisé par les applications VoIP comme les clients Skype ou BitTorrent P2P.

1
loretoparisi

Cela peut être un peu plus compliqué que ce que vous recherchez, mais TCP Hole Punching est une technique qui devrait fonctionner. http://en.wikipedia.org/wiki/TCP_hole_punching

Alternativement, UPnP fonctionne très bien pour les routeurs/pare-feu qui le prennent en charge.

1
Matthew