Portál AbcLinuxu, 9. května 2025 21:01

Dotaz: Solaris ignoruje SO_REUSEADDR aneb Jak na TCP „multicast“

13.5.2009 13:28 Andrej | skóre: 51 | blog: Republic of Mordor
Solaris ignoruje SO_REUSEADDR aneb Jak na TCP „multicast“
Přečteno: 265×
Odpovědět | Admin

Ahoj, mám dotaz ohledně jednoduchého problému. V TCP každý accept() vytváří na straně serveru nové spojení, které má stále stejnou místní adresu i port. Dá se něčeho podobného docílit na straně klienta?

Úkol je jednoduchý: Démon, který (zejména kvůli firewallu) bude přijímat i navazovat TCP spojení pořád ze stejného portu. Každý démon může chtít navázat spojení (paralelně) s několika dalšími, případně přijmout několik příchozích spojení.

Strinktně vzato, TCP spojení je čtveřice (adresa, port, adresa, port). Proto si myslím, že by neměl být problém z jedné adresy a z jednoho portu navázat víc spojení, pokud se každé z nic aspoň v jednom prvku čtveřice odlišuje. Na Linuxu tohle bez problémů funguje, ale na Solarisu ne.

Například tato (pokusná) inicializace na Linuxu projde zcela bez problémů:

sock1 = socket( AF_INET6, SOCK_STREAM, IPPROTO_TCP );
sock2 = socket( AF_INET6, SOCK_STREAM, IPPROTO_TCP );

setsockopt( sock1, SOL_SOCKET, SO_REUSEADDR, &ONE, sizeof( ONE ) );
setsockopt( sock2, SOL_SOCKET, SO_REUSEADDR, &ONE, sizeof( ONE ) );

bind( sock1, (const struct sockaddr *) &addr, sizeof( addr ) );
bind( sock2, (const struct sockaddr *) &addr, sizeof( addr ) );

Pak lze bez problémů vytvořit dvě TCP spojení z téže adresy a z téhož portu ke dvěma různým strojům. To jsem důkladně otestoval. Oba sockety můžou odesílat i přijímat data, všechno se správně doručí a prostě to funguje.

Nicméně na Solarisu nastal problém. (Ne že bych to nečekal...) Druhý bind() mi hlásí Address already in use. Vždyť jsem přece nastavil SO_REUSEADDR, tak v čem je chyba? Taky jsem zkoušel nastavit setsockopt() až po prvním bind(), ale nepomolo to.

Solaris měl kdysi bug, který byl nejspíš odstraněn natolik radikálně, že SO_REUSEADDR už prostě nefunguje. Nebo možná funguje, ale neumožňuje vícenásobný bind() na in6addr_any? Možná, ale pak je tahle vymoženost pro mě bezcenná.

Nejdůležitější otázka nakonec: Nemá se náhodou problém tohoto typu řešit nějak jinak? Připadá mi, že každý systém si vykládá SO_REUSEADDR po svém. Pak tudy cesta nevede, protože takový kód není přenositelný.

Nástroje: Začni sledovat (1) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

13.5.2009 13:38 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: Solaris igneruje SO_REUSEADDR aneb Jak na TCP „multicast“
Odpovědět | | Sbalit | Link | Blokovat | Admin

Aha, tak možná je opravdu problém s tou wildcard adresou. Linuxu to kupodivu nevadí, zatímco Solarisu ano. Solaris tedy zřejmě neumí navázat několik TCP spojení ze stejné adresy a stejného portu. Nebo jsem něco přehlédl?

13.5.2009 13:48 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: Solaris igneruje SO_REUSEADDR aneb Jak na TCP „multicast“
Odpovědět | | Sbalit | Link | Blokovat | Admin

Tak tohle vypadá dost beznadějně. Někdo už tenhle problém řešil. A nejspíš nevyřešil. :-(

13.5.2009 15:18 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: Solaris ignoruje SO_REUSEADDR aneb Jak na TCP „multicast“
Odpovědět | | Sbalit | Link | Blokovat | Admin

Vzdávám to. Když i Jabber provozuje serverová spojení z náhodných portů, asi to má svůj důvod...

[root@charon andrej]# netstat -atpn | grep 5269
tcp        0      0 :::5269                 :::*                    LISTEN      6081/java
tcp        0      0 ::ffff:95.82.129.:39267 ::ffff:62.109.141.:5269 ESTABLISHED 6081/java
tcp        0      0 ::ffff:95.82.129.:54748 ::ffff:81.2.199.30:5269 ESTABLISHED 6081/java
tcp        0      0 ::ffff:95.82.129.1:5269 ::ffff:88.86.102.:46082 ESTABLISHED 6081/java
tcp        0      0 ::ffff:95.82.129.1:5269 ::ffff:81.2.199.3:57781 ESTABLISHED 6081/java
tcp        0      0 ::ffff:95.82.129.:38551 ::ffff:88.86.102.5:5269 ESTABLISHED 6081/java
tcp        0      0 ::ffff:95.82.129.1:5269 ::ffff:208.68.163:45581 ESTABLISHED 6081/java
tcp        0      0 ::ffff:95.82.129.:52673 ::ffff:208.68.163.:5269 ESTABLISHED 6081/java

Ten zvláštní multicasting, který jsem chtěl, by sice na Linuxu fungoval, ale to je chabá útěcha. Asi se budu muset vybodnout na ohleduplnost vůči firewallu a taky používat implicitní porty.

Ach jo, zase další den času v háji. :-D

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.