2011-11-16 9 views
8

Od Beej's Guide to Network programmingJakie byłyby wady/zagrożenia związane z używaniem AF_UNSPEC?

można zmusić go do używania IPv4 lub IPv6 w dziedzinie ai_family albo zostawić je jako wartość AF_UNSPEC używać cokolwiek. To jest fajne, ponieważ twój kod może być agnostyczny w wersji IP.

Jak sam tytuł mówi - co byłoby wady (lub ryzyka, jeśli w ogóle) zawsze za pomocą AF_UNSPEC, zamiast określania IPv4 lub IPv6?

A to tylko z jednego powodu - jeśli określona jest wersja, to gwarantuje, że ta i tylko ta wersja jest obsługiwana?


Nieco background - myślę o dodanie wsparcia dla protokołu IPv6 w klient-serwer (C++) aplikacji i obie wersje powinny być wspierane. Zastanawiałem się więc, czy można użyć AF_UNSPEC, czy lepiej "rozpoznać" adres z ciągu i użyć AF_INET6 lub AF_INET, w zależności od adresu.

Odpowiedz

3

Musisz rozróżnić aplikacje klienckie i serwerowe.

Na kliencie jest to łatwe: wystarczy zadzwonić pod numer getaddrinfo() i wypróbować każdą z odpowiedzi po kolei, aż do uzyskania połączenia.

Na serwerze rzeczy są trochę trudniejsze:

  • Istnieją systemy, których IPv4 i v6 stosy są ze sobą połączone, nie wystarczy tylko słuchać na IPv6. Być może gniazdo musi być włączone, aby móc słuchać obu.
  • Inne systemy, takie jak Windows XP, mają oddzielne stosy, w których to połączenie nie jest możliwe. Tam musiałbyś pracować z kilkoma gniazdami naraz. Pozwólcie, że skupię się na następujących.

Można używać nawet na serwerach, getaddrinfo(). Tam możesz użyć flagi AI_PASSIVE w podpowiedziach. Wtedy otrzymujesz wyniki. Na tych wszystkich będziesz musiał słuchać, być może włączając flagę IPV6_V6ONLY.

accept() powinien być wykonany bez blokowania lub z select() lub poll() (nie jestem pewien, czy to drugie jest możliwe).

+0

Dzięki. Zmieniłem jeden z tagów na 'unix'. Moje pytanie dotyczy więc Linuksa. Próbowałem z 'AF_UNSPEC' i wydaje się, że działa idealnie dla obu wersji. Zastanawiałem się, czy mogę po prostu użyć tego w ten sposób, lub lepiej poradzić sobie z kilkoma gniazdami. –

+0

Spójrz na http://stackoverflow.com/questions/8113805/usage-of-getaddrinfo-with-ai-passive. Napisałem o tym wniosek ... – glglgl

+0

Ah, widzę teraz. Zajęło mi tyle czasu, aby zrozumieć, co dokładnie masz na myśli: D Jestem po prostu trochę nowy w programowaniu sieciowym. Dzięki, +1 i zaakceptowany (nawet jeśli to nie odpowiada na pytanie w tytule, ale pomogło mi oczyścić umysł :)) –

3

sposobu rzeczy powinny być:

Wnioski powinny być warstwy 3 agnostykiem. Łączenie z innym systemem powinno odbywać się według nazwy. Nazwa powinna zostać przetłumaczona na jeden lub więcej adresów, a aplikacja powinna się z nimi połączyć, nie patrząc na używany protokół. W ten sposób konfiguracja sieci jest obowiązkiem administratora sieci i systemu. Jeśli IPv6 zostanie wprowadzony do sieci, aplikacja będzie nadal działać, nawet nie zauważając różnicy.

Niektóre kwestie rzeczywistego świata:

Czasami IPv6 jest źle skonfigurowane, zapora nie wie, jak radzić sobie z IPv6, IPv6 jest używany tylko w sieci lokalnej bez połączenia z Internetem, itd. To nie powinno stanowić problemu, ale czasami napotykamy na złe wdrożenie lub konfigurację. Aby poradzić sobie z tym, że IETF pracuje nad projektem o nazwie happy-eyeballs. Zapewnia to, że użytkownik nie zauważy takich problemów. Spójrz na ten szkic. Korzystanie z technik określonych w tej wersji sprawi, że Twoja aplikacja będzie działać dobrze dla wszystkich użytkowników.

-1

Jednym z zagrożeń związanych z używaniem AF_UNSPEC jest narażenie klienta na większe odpowiedzi ze strony złośliwego serwera DNS, który może próbować użyć CVE-2015-7547, aby spowodować przepełnienie bufora stosu i spowodować wykonanie złośliwego kodu przez klienta. W rzeczywistości jednym z proponowanych obejść dla znanego defektu w getaddrinfo jest zapobieganie używaniu AF_UNSPEC jako szczegółowego here w raporcie o błędzie. Wada przepełnienia dla odpowiedzi DNS większej niż 2K wpływa na glibc z 2.9 i jest ustalona w 2.23. Wpływa to na większość obecnie zainstalowanych dystrybucji systemu Linux.

Powiązane problemy