19.05.2016

Повний Огляд NAT

Original: http://www.raknet.net/raknet/manual/natpunchthrough.html

Що таке NAT?

NAT короткий для трансляції мережевих адрес. Він використовується маршрутизаторами для відображення адреси за маршрутизатором на одну адресу призначення, скориставшись різними портами. Наприклад, якщо у вас є два комп’ютера за маршрутизатором, але тільки один провайдер, то обидва комп’ютера будуть використовувати один і той же IP-адресу, але з різними портами джерела, ніж те, що насправді призначення застосунку. Маршрутизатор зберігає таблицю пошуку того, що вона забезпечує відображень, тому, коли відповідає віддалений комп’ютер він направляється на правильний локальний комп’ютер за NAT.

Проблема з NAT є те, що віддалені комп’ютери не можуть ініціювати посилає на локальних комп’ютерах, оскільки ніякого відображення поки не існує. Тому, якщо два комп’ютери, як позаду NAT намагаються підключитися, і не буде в змозі зробити це. Це проблема, з підтримкою голосового зв’язку, пірінгових гри, або гри, де користувачі та хост-хост знаходиться за NAT. У колишні часи ваші користувачі повинні піти на їх екран конфігурації маршрутизатора і налаштувати відображення. Проте, в сучасних додатках користувачі зазвичай не потрібно, щоб зробити це, завдяки NatPunchthrough.

NAT Огляд

Плагін NatPunchthroughClient.cpp вимагає розміщується призначений для користувача сервер, а не за NAT, працює NatPunchthroughServer.cpp, що обидва клієнти можуть підключитися. Сервер знаходиться зовнішній IP-адреса кожного клієнта, і сказати, як клієнтам, щоб підключитися до цією адресою в той же час. Якщо це не вдається, кожен клієнт буде намагатися оцінити порти, використовувані інший. Якщо це не вдається, то процес повторюється ще раз, у разі, якщо пізніше оцінка порт відкритий попередній порт. Якщо це також не плагін повертає ID_NAT_PUNCHTHROUGH_FAILED.

Примітка 1: Якщо ви публікуєте через Steam, ми також забезпечуємо SteamLobby, який використовує сервери, розміщені на Valve, в цьому випадку NATPunchthrough не варто.
Примітка 2: NAT Punchthrough не є необхідним, якщо виключно за допомогою IPV6.
Примітка 3: Якщо ваша гра тільки клієнт / сервер, ви можете просто застосовувати, що сервери повинні підтримувати UPNP. Див DependentExtensions \ miniupnpc-1.6.20120410. Більшість маршрутизаторів підтримують це в ці дні, і припускаючи UPNP проходить, будь-яка людина може підключитися до вас.

NAT Punchthrough Алгоритм

1.Peer P1 хоче підключитися до рівного P2, обидва з яких з’єднані з третьої системою Non-NAT, F
2.Peer P1 називає OpenNAT () з RakNetGUID (унікальний ідентифікатор) Р2 до F.
3.F повертає збій, якщо P2 не підключений, або вже намагається punchthrough до P1.
4.F запам’ятовує стан зайнятості P1 і P2. Якщо будь-яка Р1 або Р2 зайнята, то запит поміщається в чергу. В іншому випадку F запити останнім часом використовується зовнішній порт від P1 і P2. P1 і P2 позначаються як зайнятий.
5.Якщо будь-яка P1 або P2 не відповідають punchthrough зазнає невдачі з ID_NAT_TARGET_UNRESPONSIVE і прапор зайнятості знята з охорони. В іншому випадку, F відправляє повідомлення датуються підключення до P1 і P2 одночасно.
6.P1 і P2 діють однаково в цій точці. По-перше, вони посилають кілька дейтаграм UDP один одного внутрішніх адрес LAN. Потім вони намагаються зовнішній IP / порт один одного, як показано на F. порти спробували послідовно, аж до MAX_PREDICTIVE_PORT_RANGE.
7.Якщо в будь-який момент дейтаграмма прибуває з віддаленого вузла, ми входимо в державну PUNCHING_FIXED_PORT. Датаграми відправляються тільки цієї комбінації IP / порт решти алгоритму. Якщо наша відповідь приходить на віддаленій системі, NAT вважається двонаправленим і ID_NAT_PUNCHTHROUGH_SUCCEEDED повертається користувачеві.
8.Коли NAT відкрита, або якщо ми вичерпаємо всі порти, P1 і P2 відправити F, що вони готові до нового punchthrough спробу.

Алгоритм ЕФЕКТИВНОСТІ залежить від типів NAT, що беруть участь. Вона буде працювати з NAT в залежності від того є найбільш вирішальним.

Повний конус NAT: Приймає будь-які датаграми до порту, який раніше використовувався. Чи прийме перший дейтаграмму від віддаленого вузла.

Адреса-обмеженого конуса NAT: Приймає датаграми порт доти, як IP-адреса джерела дейтаграми є система, яку ми вже відправили в. Буде приймати першу дейтаграмму, якщо обидві системи надсилають одночасно. В іншому випадку, буде приймати перший дейтаграмму після того, як ми послали одну дейтаграмму.

Порт-обмеженого конуса NAT: Те ж, що адреса з обмеженням конуса NAT, але ми повинні були відправити як правильний віддалений IP-адреса і правильний віддалений порт. Той же адреса і порт джерела до іншого призначенням використовує те ж саме відображення.

Симетричний NAT: інший порт вибирається для кожного віддаленого призначення. Той же адреса і порт джерела до іншого призначенням використовує інше відображення. Так як порт буде відрізнятися, перша зовнішня спроба punchthrough зазнає невдачі. Для цієї роботи потрібно його порт-передбачення (MAX_PREDICTIVE_PORT_RANGE> 1) і що маршрутизатор вибирає порти послідовно.
Графік

Безымянный

* NO все ще може підключитися, якщо оцінка порт працює, але не може покладатися.

Реалізація клієнта

1.Створіть екземпляр плагіна: NatPunchthroughClient natPunchthroughClient;
2.Встановіть плагін до примірника RakPeerInterface: rakPeer-> AttachPlugin (& natPunchthroughClient);
3.Підключення до сервера, і чекати ID_CONNECTION_REQUEST_ACCEPTED. Використовуйте наступний рядок, щоб використовувати безкоштовний сервер наданий RakNet: rakPeer-> Connect ( “natpunch.jenkinssoftware.com”, 61111, 0, 0);
4.Виклик OpenNAT з RakNetGUID (глобальний унікальний ідентифікатор) віддаленої системи, яку планується отримати доступ. Для того, щоб отримати RakNetGUID, ви повинні або передати його з вашим власним кодом на сервері, завантажте його на PHPDirectoryServer, або використовувати плагін, який зберігає його, наприклад, LightweightDatabase: natPunchthroughClient.OpenNAT (remoteGuid, serverSystemAddress);. Для того, щоб прочитати свій власний RakNetGUID, використовуйте RakPeerInterface :: GetGuidFromSystemAddress (UNASSIGNED_SYSTEM_ADDRESS);
5.Почекайте деякий час. Це може зайняти більше 10 секунд, щоб спробувати всі можливі порт двічі, хоча він часто працює протягом декількох секунд. Якщо ви хочете, щоб отримати текстові повідомлення про те, що відбувається, ви можете використовувати NatPunchthroughClient :: SetDebugInterface ()
6.ID_NAT_PUNCHTHROUGH_SUCCEEDED означає, що punchthrough вдалося, і ви повинні бути в змозі з’єднати або відправити інші повідомлення на віддалену систему. Пакет :: SystemAddress це адреса системи тепер ви можете підключитися. Будь-яке інше ID_NAT_ * означає punchthrough не вдалося. Див MessageIdentifiers.h для списку кодів і зауважень по кожному.

Реалізація сервера

1.Хост-сервер де-небудь, а не за допомогою NAT / наприклад, за брандмауером. (RakNet надає безкоштовний один в 8.17.250.34:60481~~pobj, однак ви можете розмістити свої власні для послідовної безперебійної роботи).
2.Створіть екземпляр плагіна: NatPunchthroughServer natPunchthroughServer;
3.Встановіть плагін: rakPeer-> AttachPlugin (& natPunchthroughServer);
4.Не забудьте викликати RakPeerInterface :: STARTUP () і RakPeerInterface :: SetMaximumIncomingConnections (max_connections);

Використання класу NatPunchthrough

Дивіться приклади \ Samples \ NATCompleteClient і \ Samples \ NATCompleteServer

UDP проксі

З деяким поганою якістю або домашні маршрутизатори, цілком можливо, що NAT punchthrough не працюватиме. Наприклад, маршрутизатор, який вибирає новий випадковий порт для кожного вихідного з’єднання, і буде вирішувати тільки вхідні підключення до цього порту, ніколи не буде працювати. Це відбувається приблизно в 5% випадків. Щоб впоратися з цією справою, RakNet забезпечує систему UDPProxy. По суті, він використовує сервер, який ви запускаєте для маршрутизації повідомлень між джерелом і комп’ютером клієнта-одержувачем прозоро. Це працює навіть для маршрутизації дейтаграм з ігор не використовуючи RakNet (хоча вам потрібно RakNet налаштувати пересилання). Поєднання NATPunchthrough і UDPProxy повинні включити будь-яку систему для підключення до будь-якої іншої системи, з імовірністю успіху 100%, за умови, ви готові прийняти у себе достатню кількість проксі-серверів, щоб пересилати весь трафік.

Система UDP

проксі-сервер використовує 3 основні класи:

UDPProxyClient: Робить запити UDPProxyCoordinator на перенаправлення установки. Це клас працює клієнт.
UDPProxyCoordinator: Працює на сервері, який буде отримувати всі запити від UDPProxyClient. Крім того, отримує все логіни з UDPProxyServer
UDPProxyServer: Насправді робить пересилання дейтаграм UDP, за допомогою складеного примірника UDPForwarder.cpp

Реалізація Клієнт:

1.Створіть екземпляр плагіна: UDPProxyClient udpProxyClient;
2.Виведіть клас від RakNet :: UDPProxyClientResultHandler, щоб отримувати повідомлення про події в системі.
3.Встановіть плагін до примірника RakPeerInterface: rakPeer-> AttachPlugin (& udpProxyClient);
4.Виклик UDPProxyClient :: SetResultHandler () класу, створений на кроці 2.
5.Спробуйте NATPunchthrough в першу чергу. Якщо ви отримуєте ID_NAT_PUNCHTHROUGH_FAILED для системи, яка ініціювала NATPunchthrough, перейдіть до кроку 6. Обидві системи будуть повертати ID_NAT_PUNCHTHROUGH_FAILED, однак, тільки одна система повинна запустити систему проксі.
6.Виклик UDPProxyClient :: RequestForwarding з адресою координатора, адреса, який ви хочете переслати з (UNASSIGNED_SYSTEM_ADDRESS для вашого власного), адресу, яку ви хочете направити, і як довго тримати пересилання активним на будь-яких даних. Наприклад:
SystemAddress coordinatorAddress;
coordinatorAddress.SetBinaryAddress ( “8.17.250.34”);
coordinatorAddress.port = 60481;
udpProxyClient.RequestForwarding (coordinatorAddress, UNASSIGNED_SYSTEM_ADDRESS, p-> systemAddress, 7000);
7.Припускаючи, що ви підключені до координатора, а координатор працює плагін, ваше подія класу обробника, створений на кроці 2 повинен отримати зворотний виклик протягом секунди або два. UDPProxyClientResultHandler :: OnForwardingSuccess буде повернутий, якщо UDPProxyServer був призначений для пересилки дейтаграми з вихідної системи, зазначеної в пункті 6, до цільової системі, зазначеної на кроці 6. Наприклад, для підключення до системи віддаленого використання: rakPeer-> Connect ( proxyIPAddress, ProxyPort, 0, 0);

Якщо більш ніж один сервер доступний, і обидві системи ретрансляції вихідних і цільових працюють RakNet, то джерело і мета буде автоматично пінг всі доступні сервери. Сервери будуть зроблені в порядку низькою пінг суму до найвищого. Це засновано на припущенні про те, що найнижчий пінг сума дає вам сервер, який має найкоротший шлях між двома системами, і тому найменш лага.

Здійснення Координатор:

1.Створіть екземпляр плагіна: UDPProxyCoordinator udpProxyCoordinator;
2.Встановіть плагін до примірника RakPeerInterface: rakPeer-> AttachPlugin (& udpProxyCoordinator);
3.Встановити пароль на координатора для серверів, щоб використовувати udpProxyCoordinator.SetRemoteLoginPassword (COORDINATOR_PASSWORD);
4.Не забудьте викликати RakPeerInterface :: STARTUP () і RakPeerInterface :: SetMaximumIncomingConnections (max_connections);

Реалізація сервера:

1.Створіть екземпляр плагіна: UDPProxyServer udpProxyServer;
2.Встановіть плагін до примірника RakPeerInterface: rakPeer-> AttachPlugin (& udpProxyServer);
3.Підключення до координатора
4.Вхід для координатора. Це може бути зроблено під час виконання, так що ви можете динамічно додавати більше переадресації серверів, як ваша гра є більш популярним.
udpProxyServer.LoginToCoordinator (COORDINATOR_PASSWORD, coordinatorSystemAddress);
Якщо координатор плагін знаходиться в тій же системі, що і плагін сервера, використовуйте:
udpProxyServer.LoginToCoordinator (COORDINATOR_PASSWORD, rakPeer-> GetInternalID (UNASSIGNED_SYSTEM_ADDRESS));
5.Якщо ви хочете, щоб отримати зворотні виклики, як відбуваються події (особливо авторизуватися на сайті, відмова) випливають з RakNet :: UDPProxyServerResultHandler і зареєструвати похідний клас з UDPProxyServer :: SetResultHandler ()

Діаграма станів з UDP проксі

natpunchpanel1smallnatpunchpanel2smallnatpunchpanel3smallnatpunchpanel4small

natpunchpanel5smallnatpunchpanel6smallnatpunchpanel7small

Хостинг-сервер

Вимоги до сервера

1.Ні трансляцію мережевих адрес.
2.Жоден брандмауер, або брандмауер не відкритий відповідних портів.
3.Статична IP-адреса. Dynamic DNS є одним із способів обійти цю вимогу.
4.Компіляція з __GET_TIME_64BIT, якщо ви хочете запустити сервер більше місяця без перезавантаження
5.Достатню пропускну здатність для обробки всіх з’єднань

Комерційні хостинг рішення

1.Hypernia
Філії по всьому світу. Сервери окремі машини. Починаючи з $ 150 в місяць

Якщо ви знайдете більш хостинг рішення, зв’яжіться з нами, і він буде доданий в цей список.

About The Author

admin

Comments are closed.