Sieć P2P i NAT

0

Nie chodzi o konkretną technikę programowania (język, biblioteki), tylko o samą ideę i zasadę działania P2P.

Co do działania, to ja rozumiem, że P2P polega na tym, że każdy może połączyć się z każdym, natomiast połączenie TCP/IP wymaga zewnętrznego adresu i portu urządzenia, na którym jest serwer, a klient nie musi mieć (może być za NATem).

Załóżmy, że są czterej użytkownicy programu, który może być i serwerem i klientem, tylko, że mają taką konfigurację swoich urządzeń:
Adam - jest za NATem
Barbara - jest za NATem
Celina - posiada zewnętrzny IP
Dorota - posiada zewnętrzny IP

Ci, którzy mają NAT nie mają ustawionego przekierowania na routerze, nie ma ograniczeń portów połączeń, żadnych proxy, VPN itp. Z powyższego wnioskuję, że:
Adam NIE MOŻE podłączyć się do Barbary i Barbara NIE MOŻE podłączyć się do Adama, czyli łączność Adam-Barbara NIE MOŻE być zestawiona
Adam może podłączyć się do Celiny, ale Celina NIE MOŻE podłączyć się do Adama, czyli łączność Celina-Dorota może być zestawiona wyłącznie z inicjatywy Adama
Celina może podłączyć się do Doroty i Dorota może podłączyć się do Celiny, czyli łączność Celina-Dorota może być zestawiona z inicjatywy Celiny lub Doroty
Czy mam rację?

Przekładając na język grafów, między tymi użytkownikami można narysować skierowany, gdzie między Celiną i Dorotą będą dwa krawędzie w przeciwnych kierunkach, między Adamem i Barbarą nie będzie żadnej krawędzi, od Adama lub Barabary do Celiny lub Doroty będzie jedna krawędź jednokierunkowa.

Załóżmy, że chciałbym napisać program do wymiany plików działający jako P2P (coś, jak BitTorrent, eMule, eDonkey, Gnutella) na tych czterech komputerach. Pomińmy kwestie przekazywania listy udostępnionych plików oraz przeszukiwania sieci. ZTCW, przy przesyłaniu pliku łączą się dwa komputery bezpośrednio, bo na tym polega P2P, przez co nie da się takiej sieci unieruchomić przez wyłączenie konkretnego urządzenia.

Jeżeli Celina chce pobrać plik od Doroty lub Dorota od Celiny, to nie ma żadnego problemu. Po prostu należy podłączyć się po adresie IP i porcie, każdy tutorial opisuje, jak nasłuchiwać na porcie i przyjąć połączenie, oraz jak podłączyć się do innej maszyny po adresie IP i porcie. Podobnie w przypadku, gdy Adam chce pobrać plik od Celiny, również nie ma problemu (ale w drugą stronę, to już nie bardzo).

Pytanie jest następujące:

Jak będzie wyglądać sytuacja, gdy Celina chce pobrać plik od Adama, skoro bezpośrednio nie może się podłączyć? Jeżeli Adam przypadkowo podłączył się do Doroty, to czy w takiej sytuacji Celina podłączy się do Doroty i program na komputerze Doroty wykorzystując zestawione połączenie z Adamem zażąda od Adama zainicjowanie połączenia z Celiną, a jak Celina przyjmie połączenie od Adama, to wtedy rozpocznie się transfer właściwych danych?

Jeżeli tak, to jak będzie wyglądało w przypadku, gdy Adam chce pobrać plik od Barbary? Czy w takiej sytuacji cały transfer będzie szedł przez komputer Celiny lub Doroty (do Celiny lub Doroty może być podłączony zarówno Adam, jak i Barbara), czy jednak da się zestawić bezpośrednie połączenie między dwoma urządzeniami za NATem? Jeżeli się da, to jak to się robi na ogół w sieciach P2P?

Jeśli chodzi o język i technologię, to C#/.NET, lub Java SE (obsługa server-client wygląda prawie tak samo w obu tych technologiach).

Nie szukając daleko, P2P jest w Skype lub TeamViewer. Nie wyobrażam sobie, żeby przekaz audio/video wszystkich użytkowników szedł przez serwer TeamViewer lub Skype, bo przy kilku milionach się zarżnie, a nawet, jak to udźwignie, to byłoby to nie rozsądne.

0

Ogólnie to dobrze rozumujesz. Jeśli Adam ma już połączenie z Dorotą, to jeśli Celina coś od niego chce to musi wykorzystać Dorotę do zasygnalizowania Adamowi chęci połączenia i czekać aż on się połączy.

W przypadku obu hostów za NATem istnieją protokoły umożliwiające nawiązanie bezpośredniego połączenia (z pomocą zewnętrznego serwera) np. STUN, ale często nie działają ze współczesnymi NATami. Wtedy pozostaje użycie zewnętrznego serwera jako proxy.

Jeśli planujesz napisać jakąś konkretną aplikację to możesz zainteresować się standardem WebRTC, tam jest wbudowana obsługa serwerów STUN do wybijania dziur w NATcie i TURN do proksowania połączenia jeśli STUN zawiedzie, potrzebny jest też signalling server który będzie pośredniczył w nawiązywaniu połączenia pomiędzy hostami.

0
mad_penguin napisał(a):

Ogólnie to dobrze rozumujesz. Jeśli Adam ma już połączenie z Dorotą, to jeśli Celina coś od niego chce to musi wykorzystać Dorotę do zasygnalizowania Adamowi chęci połączenia i czekać aż on się połączy.

W przypadku obu hostów za NATem istnieją protokoły umożliwiające nawiązanie bezpośredniego połączenia (z pomocą zewnętrznego serwera) np. STUN, ale często nie działają ze współczesnymi NATami. Wtedy pozostaje użycie zewnętrznego serwera jako proxy.

Jeśli planujesz napisać jakąś konkretną aplikację to możesz zainteresować się standardem WebRTC, tam jest wbudowana obsługa serwerów STUN do wybijania dziur w NATcie i TURN do proksowania połączenia jeśli STUN zawiedzie, potrzebny jest też signalling server który będzie pośredniczył w nawiązywaniu połączenia pomiędzy hostami.

Jak chodzi o WebRTC, to problem jest mniejszy, bo to przeglądarka inicjuje połączenie i to zawsze do serwera HTTP, który ma zewnętrzny IP. Potem jest WebSocket czy coś innego, że wtedy to serwer HTTP może zainicjować połączenie i jakąś czynność. Moim zdaniem, tu jest architektura z serwerem centralnym.

Jakieś 10 lat temu zrobiłem taki eksperyment, że na dwóch komputerach w domu uruchomiłem Skype i zrobiłem połączenie (rozmowę) miedzy sobą. Jednak, jak odłączyłem internet (ale komputery miały połączenie cały czas), to połączenie się zerwało, czyli musiało coś wychodzić na zewnątrz lub wchodzić coś z zewnątrz podczas trwania połączenia, albo na zewnątrz był taki właśnie proxy. Na 80% oba komputery nie były za NATem i miedzy sobą mogły się łączyć po zewnętrznym IP.

W architekturze z serwerem centralnym (czyli np. Napster, Skype, TeamViewer), to do tego serwera zgłasza się każdy użytkownik i to ten serwer wysyła i odbiera żądania nawiązywania łączności w zależności od potrzeb.

A w architekturze bez serwera centralnego to chyba musi być kilka wyróżnionych serwerów z zewnętrznym IP i przyłączenie użytkownika to tak naprawdę podłączenie się do wyróżnionego serwera, który bada, czy da się zainicjować podłączenie do użytkownika (czy jest za NAT, czy ma blokady portów i ruchu) i na podstawie tego ustala sposób nawiązywania połączeń z tym użytkownikiem, a wyróżnione serwery mogą się zmieniać, przy czym ich aktualna lista musi być jakoś publikowana, żeby można było się podłączyć. Czy to tak właśnie jest?

0
andrzejlisek napisał(a):

Nie szukając daleko, P2P jest w Skype lub TeamViewer. Nie wyobrażam sobie, żeby przekaz audio/video wszystkich użytkowników szedł przez serwer TeamViewer lub Skype, bo przy kilku milionach się zarżnie, a nawet, jak to udźwignie, to byłoby to nie rozsądne.

Nie ma od kiedy został wykupiony przez MS.

Jak będzie wyglądać sytuacja, gdy Celina chce pobrać plik od Adama, skoro bezpośrednio nie może się podłączyć? Jeżeli Adam przypadkowo podłączył się do Doroty, to czy w takiej sytuacji Celina podłączy się do Doroty i program na komputerze Doroty wykorzystując zestawione połączenie z Adamem zażąda od Adama zainicjowanie połączenia z Celiną, a jak Celina przyjmie połączenie od Adama, to wtedy rozpocznie się transfer właściwych danych?

To zależy od protokołu i implementacji. Mogą istnieć nody pośredniczące, zestawiające połączenie albo pełniące rolę proxy.

A w architekturze bez serwera centralnego to chyba musi być kilka wyróżnionych serwerów z zewnętrznym IP i przyłączenie użytkownika to tak naprawdę podłączenie się do wyróżnionego serwera, który bada, czy da się zainicjować podłączenie do użytkownika (czy jest za NAT, czy ma blokady portów i ruchu) i na podstawie tego ustala sposób nawiązywania połączeń z tym użytkownikiem, a wyróżnione serwery mogą się zmieniać, przy czym ich aktualna lista musi być jakoś publikowana, żeby można było się podłączyć. Czy to tak właśnie jest?

Tak jest. Ktoś/coś musi nie być za NATem. Nody z publicznymi adresami ip mogą być traktowane inaczej niż te za NATem. Można je połączyć tak by tworzyły swego rodzaju sieć (nawizjmy to overlay network) i pomagały łączyć się biednym nodom za NATem z innymi nodami za NATem. Wystarczy, że znajdzemy tego nadrzędnego noda, do którego podłączony jest ten upośledzony node. Informacje o nodach można trzymać np. w rozprosoznych tablicach hashujących, rozluźnić trochę wymagania co do konsystencji tych list i wykorzystać ewentualną konsytencję w postaci protokołów plotkowania do replikacji tych list. W ten oto sposób mamy dynamiczną sieć nodów centralnych. Oczywiście, parę nodów musi być powszechnie znanych by obsłużyć rozruch.

0

Nie ma czegoś takiego jak IP wew i zew ;) Dokumenty IANA i IEEE bardzo jasno precyzują nazewnictwo tj: ip prywatne i publiczne.
Zawsze mnie "terepocze" jak słyszę... ip zewnętrzne ;)
Można przeżyć te określenia wypowiadane przez murarza czy malarza... ale informatykowi...a szczególnie programiście nie wypada ich używać.

Są protokoły zestawiające połączenia oraz sygnalizujące. Dzięki nim 2 osoby za Natem mogą p2p wymieniać dane.
Ale musi być na "moment" serwer zestawiający połączenie do którego oboje się łączą (sygnalizują gotowość przyjęcia połączenia).
Czasem (w zależności od ustawień modemu/routera/firewalla) może być z tym problem gdyż urządzenie wyrzuca/zrzuca pakiety pochodzące od IP na które SAMO jako pierwsze nie nawiązało połączenia.
Te sytuacje ratują protokoły wspierające tego typu sytuacje, i są supprtowane przez routery (nawet low budgetowe -> domowe jak np Linksys).
Dzięki temu router jest informowany że na port może przyjść połączenie z obcego-3-go IP i ma przeprowadzić translacje jak dla pakietu z IP od komputera do którego nawiązał komunikacje.

do wyszukania: Stun, H323/H225, Sip, inne zestawiające połączenia miedzy adresami za nat'em.

1 użytkowników online, w tym zalogowanych: 0, gości: 1