2012-01-27 148 views
1

我創建具有以下PARAMS插座:行爲connect()的IPv4和IPv6地址

hints.ai_family = AF_UNSPEC; 
hints.ai_socktype = SOCK_STREAM; 
getaddrinfo(serverName, port, &hints, &res); 
sFd = socket (res_node->ai_family, SOCK_STREAM, 0); 

我然後進行連接的可能會或可能不會出現IPv4和IPv6服務器地址電話。當服務器不可達時,它在IPv4和IPv6地址的情況下具有不同的行爲。

在v4的情況下,它會在返回錯誤之前卡住很長時間(某些內部默認超時)。但是,在IPv6的情況下,行爲會發生變化。對於某些地址,呼叫立即返回錯誤,例如地址像1111 :: 22,而對於一些則需要更長的時間,例如, fec0:60:69bc:94:211:25ff:fec4:6但仍然比IPv4超時少。

任何人都可以解釋行爲的差異?

+1

你有使用例如檢查wireshark電線上發生了什麼?可能是因爲ipv4 syns被丟棄,而ipv6則返回一些icmp錯誤。 – PlasmaHH 2012-01-27 14:39:06

+0

該行爲很可能是操作系統特定的。它也可能取決於您和目標網絡之間的網絡拓撲。 – 2012-01-27 15:01:08

+0

通常,如果主機無法找到路由,則遠程連接可能會立即失敗,但如果中間路由器無法路由或防火牆會阻止該連接,則會立即失敗,但仍然是異步連接,則立即連接到本地主機應立即成功(或失敗)重置,如果目標主機可訪問但無響應或者防火牆以靜默方式丟棄SYN,則只會超時。 – Useless 2012-01-27 15:39:54

回答

0

當對特定目標主機(協議)的路由查找產生不可達/禁止/拒絕/等時,connect()會立即失敗。否則,它必須發送探測(ARP/NDISC,以及潛在的L4數據包,如TCP SYN/SCTP INIT)。

路由查找例如一個系統沒有對全球IPv6單播路由:

$ ip r g 2a01::1 
unreachable 2a01::1 from :: dev lo table unspec proto kernel src fe80::224:beff:fec2:7f16 metric -1 error -101 hoplimit 255 

注意區別爲IPv6連接的主機:

$ ip r g 2a01::1 
2a01::1 from :: via fe80::2d0:3ff:fe93:d123 dev eth0 src 2001:527:500:770f:19e:84ff:fe9e:878 metric 0