IPv4 a IPv6 na stejném portu

programmer

IPv4 a IPv6 na stejném portu
« kdy: 15. 04. 2011, 23:39:41 »
Dobry den,

jak lze udelat to, aby ma aplikace naslouchala na jednom portu na obou protokolech (IPv4/IPv6)? Kdyz to udelam klasickou cestou, tak mi u bind() hlasi chybu "Address already in use".

Demonstrace:
Kód: [Vybrat]
...
struct sockaddr_in x;
x.sin_family = AF_INET;
x.sin_port = htons(123);
x.sin_addr.s_addr = INADDR_ANY;

struct sockaddr_in6 y;
y.sin6_family = AF_INET6;
y.sin6_port = htons(123);
y.sin6_addr = in6addr_any;

int sx = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
int sy = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);

bind(sx, (struct sockaddr *)&x, sizeof(x)); perror("bind4");
bind(sy, (struct sockaddr *)&y, sizeof(y)); perror("bind6");
...


$ ./run
bind4: Success
bind6: Address already in use
« Poslední změna: 15. 04. 2011, 23:59:17 od Petr Krčmář »


eL

Re: IPv4 a IPv6 na stejném portu
« Odpověď #1 kdy: 16. 04. 2011, 15:01:29 »
struct sockaddr_in6  ma navic jeste nejake hodnoty (the sin6_flowinfo, sin6_scope_id), ktere by se mely iniciovat..

Ales Hakl

Re: IPv4 a IPv6 na stejném portu
« Odpověď #2 kdy: 17. 04. 2011, 03:25:55 »
IPv6 naslouchajici socket sam o sobe muze fungovat i pro IPv4. Jestli se tak deje ovlivnuje priznak IPV6_V6ONLY, na vetsine distribuci Linuxu (dulezita vyjimka je Debian) je vychozi hodnota nula (to je koneckoncu doporucene specifikaci), tedy IPv6 sockety naslouchaji i pro v4. Proto se vam po prirazeni v4 socketu uz nepovede priradit v6. Pokud chcete naslouchat na objim, tak budto tento priznak nastavte na 1 a vytvorte dva sockety, nebo na nula a vamy kyzeny efekt dostanete rovnou bez prace. Duvod proc pouzivat dva ruzne je ten, ze pak muzete odlisit IPv4 a IPv6 bez toho, abyste musel zkoumat zdrojovou adresu (coz se popravde receno hodi zejmena tehdy, kdyz neco chcete delat s tou adresou, nicmene treba vypsani do nejakeho logu si tim marginalne zjednodusite).

programmer

Re: IPv4 a IPv6 na stejném portu
« Odpověď #3 kdy: 18. 04. 2011, 10:11:07 »
IPv6 naslouchajici socket sam o sobe muze fungovat i pro IPv4. Jestli se tak deje ovlivnuje priznak IPV6_V6ONLY, na vetsine distribuci Linuxu (dulezita vyjimka je Debian) je vychozi hodnota nula (to je koneckoncu doporucene specifikaci), tedy IPv6 sockety naslouchaji i pro v4. Proto se vam po prirazeni v4 socketu uz nepovede priradit v6. Pokud chcete naslouchat na objim, tak budto tento priznak nastavte na 1 a vytvorte dva sockety, nebo na nula a vamy kyzeny efekt dostanete rovnou bez prace. Duvod proc pouzivat dva ruzne je ten, ze pak muzete odlisit IPv4 a IPv6 bez toho, abyste musel zkoumat zdrojovou adresu (coz se popravde receno hodi zejmena tehdy, kdyz neco chcete delat s tou adresou, nicmene treba vypsani do nejakeho logu si tim marginalne zjednodusite).

Dekuji za odpoved. Moc jste mi pomohl.

Re: IPv4 a IPv6 na stejném portu
« Odpověď #4 kdy: 19. 04. 2011, 07:38:38 »
Ad Debian: Jen dodam, ze vychozi hodnota je:
0 v Lennym, Etchi a starsich
1 ve Squeeze a novejsim

Volba se v kernelu (celosystemove) meni zapisem do /proc/sys/net/ipv6/bindv6only.

Nastavenim V6ONLY ve vlastni aplikaci celosystemovy priznak prebijete. Konkretni kod uz je otazkou googleni :)


Re: IPv4 a IPv6 na stejném portu
« Odpověď #5 kdy: 19. 04. 2011, 10:40:32 »
Ještě bych k tomuto poznamenal, že správně by měly být nové programy psány s hodnotou V6ONLY nastavenou na 1. Automatické mapování IPv4 provozu do IPv6 s sebou nese drobná bezpečnostní rizika a hlavně je nekoncepční. Taková aplikace pak nebude fungovat na OS bez podpory IPv6 a pokud ano, znamená to programovat IPv4 obsluhu dvakrát, jednou pro opravdové IPv4 a podruhé pro IPv6-mapované IPv4 adresy.

Pak bych ještě rád poznamenal, že není dobré programovat IPv6 podporu „natvrdo“, tak jak se dříve programovaly IPv4 aplikace. Jestli se časem objeví nějaké IPv7, nebo XYv9, bude potřeba aplikaci (zase) přepsat. Proto je lepší používat protokolově nezávislé rozhraní, jaké poskytuje knihovní funkce getaddrinfo (manuál obsahuje jednoduchý příklad).

Moc hezky je to celé popsáno v knize IPv6 Network Programming. I když ta je dost drahá, zvlášť když celé 3/4 obsahu (272 stran) tvoří plné texty volně dostupných RFC  :o