Question

Je veux faire du punch TCP Hole (Nat Traversal) en C #. Cela peut être fait avec un serveur Rendezvous si nécessaire. j'ai trouvé http://sharpstunt.codeplex.com/ mais ne peut pas faire fonctionner cela. Idéalement, j'ai besoin d'une méthode que je donne un numéro de port (int) en tant que paramètre qui, après un appel à cette méthode, est disponible ("Port transféré") au NAT. Il serait également OK si la méthode renvoie simplement un numéro de port qui est ensuite disponible au NAT. Quelqu'un a-t-il fait cela en C #? Pouvez-vous me donner des exemples de travail pour Sharptunt ou autre chose?

Était-ce utile?

La solution

Dans chaque scénario de réseau, TCP Hole Punching fonctionne de la même manière que le coup de poing du trou UDP. Par exemple, si deux pairs A et B sont derrière des Nats di ff érents, le premier paquet syn de chaque pair envoyé à l'autre pair ouvre un trou associé à son adresse publique dans son NAT respectif. Si le premier paquet SYN de A pour B atteint B de B de B avant le premier paquet SYN de B avec A Nat de B, NAT de B considère le paquet SYN de A non sollicité et le laisse tomber. Cependant, par la suite, le premier paquet SYN de B peut parcourir le NAT de A avec succès parce que NAT de A reconnaît l'adresse publique de B comme la destination de la session sortante que A a initiée.

Donc oui. Il est possible de TCP Holepunch. Je ne vois pas pourquoi quelqu'un penserait le contraire.

De plus, pourriez-vous ne pas créer ce type de bahavior manuellement? Il n'a pas besoin de dépendre d'un protocole spécifique tant que les étapes sont les mêmes pour rassembler toutes les informations requises.

En général, le coup de poing du trou TCP (3.2.1) se déroule comme suit:

Clients: A, serveur B: S

• A utilise sa connexion avec S pour demander à S une connexion avec B. • S répond à A avec les adresses privées et publiques de B, et envoie simultanément les adresses de A à B.

• A et B font de manière asynchrone des connexions sortantes (envoyer des paquets syn) aux adresses publiques et privées de l'autre, du même port qu'ils s'inscrivaient avec S. ports TCP locaux.

• A et B attendent une réponse SYN-ACTING à leurs paquets de synchronisation ou une demande de connexion entrante (SYN Packet). Si une connexion échoue, le pair peut le réessayer jusqu'à une période de délai maximum.

• Une fois le processus de poignée de main à trois termes terminé, les pairs s'authentifient mutuellement. Si l'authentification échoue, les pairs ferment cette connexion et attendent qu'une autre connexion soit authentifiée avec succès. La première connexion authentifiée avec succès sera utilisée pour transférer des données TCP.

(Je sais que ce n'est pas vraiment une réponse mais il n'y avait pas assez de place pour un commentaire).

Autres conseils

La question est assez ancienne, mais pour tous ceux qui recherchent une solution, vous devriez jeter un œil au Projet Open.NAT C'est vraiment facile à utiliser et à travailler avec UPNP et PMP NATS!

Disons que vous souhaitez transmettre le port externe 1700 vers le port local 1600, tout ce que vous avez à faire est:

var discoverer = new NatDiscoverer();
var device = await discoverer.DiscoverDeviceAsync();
await device.CreatePortMapAsync(new Mapping(Protocol.Tcp, 1600, 1700, "The mapping name"));

Vous pouvez également répertorier tous les mappages existants, afin que vous puissiez valider que votre port n'est pas déjà utilisé.

var sb = new StringBuilder();
var ip = await device.GetExternalIPAsync();

sb.AppendFormat("\nAdded mapping: {0}:1700 -> 127.0.0.1:1600\n", ip);
sb.AppendFormat("\n+------+-------------------------------+--------------------------------+------------------------------------+-------------------------+");
sb.AppendFormat("\n| PROT | PUBLIC (Reacheable)           | PRIVATE (Your computer)        | Descriptopn                        |                         |");
sb.AppendFormat("\n+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+");
sb.AppendFormat("\n|      | IP Address           | Port   | IP Address            | Port   |                                    | Expires                 |");
sb.AppendFormat("\n+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+");
foreach (var mapping in await device.GetAllMappingsAsync())
{
    sb.AppendFormat("\n|  {5} | {0,-20} | {1,6} | {2,-21} | {3,6} | {4,-35}|{6,25}|",
        ip, mapping.PublicPort, mapping.PrivateIP, mapping.PrivatePort, mapping.Description, mapping.Protocol == Protocol.Tcp ? "TCP" : "UDP", mapping.Expiration.ToLocalTime());
}
sb.AppendFormat("\n+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+");
Console.WriteLine(sb.ToString());

Il y a aussi un article de blog sur Nat Traversal sur MSDN: https://blogs.msdn.microsoft.com/ncl/2009/07/27/end-to-end-connectivity-with-nat-taverversal/

Il semble que vous soyez peut-être mélangé TCP et UDP. TCP est un protocole axé sur la connexion, facilement compris par les pare-feu et les routeurs, et nécessite un initiateur (client) et un écouteur (serveur). Si le client et le serveur sont derrière des pare-feu ou NAT, vous ne pouvez pas percer un trou sans les avoir tous les deux se connecter à un serveur proxy (qui n'est pas un pare-feu). Le problème avec cela est que le proxy serait alors responsable de la transmission de tout leur trafic.

D'après votre question, il semble que vous soyez plus intéressé par le coup de poing UDP, qui exploite la graisse que l'UDP est apatride et non orientée connexion. Par conséquent, la plupart des pare-feu de suivi de l'État feront une "meilleure estimation" sur le flux de données UDP, et supposeront que le trafic partant sur un port donné recevra des réponses sur le même port et les réinstallera automatiquement. Si, en utilisant des moyens hors canal (comme un serveur TCP qui passe simplement des adresses et non des données), les deux pairs peuvent se transmettre des données sur les mêmes ports, leurs pare-feu / routeurs NAT respectifs ouvriront des trous permettant le trafic.

Quant à la façon de le faire, tout dépend de la façon dont vous allez amener l'adresse IP des pairs les uns aux autres. Une fois que vous l'avez, commencez simplement à transmettre des paquets UDP sur un port convenu et attendez une réponse.

Nous avons mis sur pied une bibliothèque appelée Icelink Cela fait du streaming P2P à l'aide de glace / étourdissement / tour avec une traversée NAT complète. Le coup de trous basé sur Stroth fonctionne pour la majorité des routeurs afin d'établir une connexion directe entre les pairs, et pour les "mauvais" routeurs, la connexion retombe à un relais au tour par tour.

http://sipsorcery.codeplex.com a un serveur d'étourdissement fonctionnel.

Sipsorcery.core -> sipsorcery.net -> étourdissement

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top