2011-11-16 637 views
8

Beej's Guide to Network programming使用AF_UNSPEC的缺點/風險是什麼?

您可以強制它使用IPv4或IPv6的ai_family領域,或將其作爲AF_UNSPEC使用什麼。這很酷,因爲你的代碼可以是IP版本不可知的。

正如標題所說 - 總是使用的,而不是指定IPv4或IPv6 AF_UNSPEC,會有什麼缺點(或風險,如果有的話)?

或者這只是一個原因 - 如果指定了版本,這將保證只有這個版本被支持?


一點背景 - 我想在客戶端 - 服務器(C++)應用程序增加了對IPv6的支持,這兩個版本應該得到支持。所以我想知道是否可以使用AF_UNSPEC或者最好從字符串中「識別」地址,並根據地址使用AF_INET6AF_INET

回答

3

您必須區分客戶端和服務器應用程序。

在客戶端上,很簡單:只需撥打getaddrinfo()並依次嘗試每個答案,直到獲得連接。

在服務器上,事情有點困難:

  • 有系統,其IPv4和V6堆棧是相互關聯的,有它足以只聽IPv6的。也許套接字必須啓用才能聽兩者。
  • 其他系統(如Windows XP)在無法連接的情況下將堆棧分離。在那裏,你將不得不同時使用幾個插座。讓我專注於以下內容。

即使在服務器上,也可以使用getaddrinfo()。你在提示中使用國旗AI_PASSIVE。然後你得到結果。在這些所有你必須聽,也許啓用IPV6_V6ONLY標誌。

accept()應該做非阻塞或select()poll()(不知道後者是否可能)。

+0

謝謝。我將其中一個標籤更改爲「unix」。所以,我的問題是關於Linux。我嘗試了'AF_UNSPEC',它似乎對兩個版本都很合適。我只是想知道我是否可以像這樣使用它,或者最好是處理幾個套接字。 –

+0

看看http://stackoverflow.com/questions/8113805/usage-of-getaddrinfo-with-ai-passive。我寫了一個關於它的結論... – glglgl

+0

啊,我現在看到了。我花了很多時間來理解你的意思:D我只是網絡編程的新手。感謝+1,並被接受(儘管這實際上並未回答標題中的問題,但幫助我清楚了我的想法:)) –

3

的事物的方式應該是:

應用程序應該是3層無關。連接到另一個系統應該按名稱完成。該名稱應該解析爲一個或多個地址,並且應用程序應該連接到它們而不必查看正在使用的實際協議。這樣的網絡配置是網絡和系統管理員的責任。如果在網絡中引入IPv6,那麼應用程序將繼續工作,甚至不會注意到差異。

一些現實問題:

有時IPv6的配置錯誤,防火牆不知道如何處理使用IPv6,IPv6的只在本地網絡中使用,而不到互聯網的連接等,這不應該是一個問題,但有時你會遇到不好的實現或配置。爲了解決這個問題,IETF正在制定一個名爲happy-eyeballs的草案。它確保用戶不會注意到這些問題。看看那個草案。使用該草案中指定的技術將確保您的應用程序適用於所有用戶。

-1

使用AF_UNSPEC的風險之一是您將客戶端暴露給惡意DNS服務器的較大響應,該惡意DNS服務器可能試圖使用CVE-2015-7547導致堆棧緩衝區溢出並導致惡意代碼被執行由客戶。事實上,對於getaddrinfo中的已知缺陷提出的一種解決方法是防止在錯誤報告中使用AF_UNSPEC作爲詳細的here。 DNS響應大於2K的溢出缺陷會影響glibc從2.9開始,並在2.23中修復。這會影響大多數當前安裝的Linux發行版。