2013-08-23 88 views
2

當我打電話getaddrinfoAF_UNSPEC,理論上它可以返回它喜歡的任何地址族:AF_INETAF_INET6,可能的AppleTalk,藍牙,數據鏈路,網絡鏈路地址...getaddrinfo可以返回哪些地址族?

在實踐中,它只是在大多數返回AF_INETAF_INET6平臺:

  • 在FreeBSD,它只能返回,同上(根據glibc的手冊頁)
  • AF_INET6(在源選中)
  • 在Linux
  • 在Windows上,同樣,「ai_family的AF_UNSPEC值表示調用方只接受AF_INET和AF_INET6地址族。」 [MSDN, getaddrinfo]

其他系統呢?有沒有平臺可以讓我們獲得其他地址結構?

我特別懷疑MacOS - 源代碼似乎從opensource.apple.com/source/Libc中丟失,並且該手冊頁沒有說明。我們在Mac測試運行中有一個不可重複的日誌文件,可能表明getaddrinfo返回了一些其他地址系列。我們支持的其他平臺是AIX,Solaris和HP-UX。

我知道我可以檢查返回的結構中的家庭。我無法猜測可能需要使用哪些有趣的字符串和提示來獲取非AF_INET(6)結果。

+0

好吧,'netdb.h'似乎表明'struct addrinfo'的'ai_family'可以是任何''PF_xxx'「,所以也許它可能是任何東西?這似乎遠非一個明確的答案,儘管......評論如果這是一個有用的地方看。另外,手冊頁確實提供了在提示中將'ai_family'設置爲'PF_UNSPEC'的參考...現在,如果只是列舉「操作系統支持的任何協議族」是什麼。 :)在示例部分有進一步的參考,它*可以是其他值,但我(如你)看不到*其他值......: -/ – lindes

回答

1

沒有任何形式的保證。當我發明了自己的協議併爲其分配了一個號碼(本地),並且我的協議可以解析您的程序給出的名稱時,允許爲我的地址系列返回一個sockaddr

基本上,如果你通過AF_UNSPEC,你可以做兩件事情之一:

  1. 住危險,假設PF_*常量映射到AF_*常量,創建該類型的插座和連接它,給你即時支持我的自制協議,或者,更好,

  2. 忽略任何結果有一個地址族,你不明白,並繼續下一個。

您需要知道,很有可能查找某個名稱,但沒有所需類型的地址。當使用AF_UNSPEC進行查找時,您將得到肯定的查找結果,並且需要自己創建錯誤條件。

由於應用程序的理想行爲是回退其他結果,以防第一個應用程序無法正常工作(請考慮使用服務器發生故障的DNS循環),可以通過遍歷結果直到一個成功並調整錯誤原因(例如,以「不需要類型的地址」開始,如果發現一個連接失敗,則切換到「目標不可訪問」)。

+0

POSIX中沒有_cross-platform_保證。有平臺特定的保證。例如,它是_guaranteed_ getaddrinfo只在Windows和BSD上返回AF_INET(6)。我要求提供特定的文檔或libc源代碼來說明哪些系列在MacOS上返回。不是「可能有別人」,而是其他人。如果MacOS libc可以返回例如AppleTalk地址,請在opensource.apple.com上向我顯示代碼。 –

+0

不,也沒有平臺保證,因爲網絡堆棧在每個模塊上都是模塊化的,因此可以將新協議掛接到它們中。我可以有一個實現了我的地址族的out-of-tree Linux內核模塊和一個添加解析器的libc Name Service Switch(NSS)模塊,這足以將新結果添加到'getaddrinfo'輸出。 –

+0

你是對的,謝謝。例如,這仍然不能真正回答你在一臺典型的Mac機器上實際獲得哪些家庭地址的問題。 –

0

POSIX說:「如果提示點的值爲AF_UNSPEC的ai_family字段應返回地址,以便與可用於指定節點名稱和/或服務名稱的任何地址族一起使用。 (POSIX getaddrinfo(3))和「ai_family的AF_UNSPEC值意味着調用者應接受任何地址族」。

事實上,即使是linux手冊頁也不完全符合您所說的:「IPv4或IPv6,例如」; OpenBSD說:「當ai_family 被設置爲PF_UNSPEC時,這意味着調用者會接受任何支持操作系統的協議族。」,所以我認爲它只是意味着「不管」(與其他參數兼容)。

我真的不知道應該通過什麼字符串getaddrinfo,抱歉。

-1

可返回的AF_ *值的範圍僅受結構類型大小的限制。自定義驅動程序/網絡返回自己的地址是完全合法的。當然,您僅限於那些您擁有標頭以匹配任意值的對象,以便理解使用特定端點的語義。

儘管您可以嘗試創建所有可能的AF_ *符號的總枚舉,但如果沒有定義其值的頭以匹配OS驅動程序用於指定該協議的名稱,則這些名稱將毫無意義。這裏僅僅是少數,我發現:

AF_IPX,AF_APPLETALK,AF_NETROM,AF_BRIDGE,AF_AAL5,AF_X25,AF_BRIDGE,AF_BLUETOOTH,AF_DECnet,AF_ATMPVC,AF_ROSE,AF_NETBEUI,AF_NETLINK,AF_ASH,AF_ECONET,AF_ATM_SVC,AF_SNA,AF_IRDA,AF_PPPOX ,AF_WANPIPE,AF_LLC等等等等。

作爲linux的Linux有socket.h中的大多數,但是這些值並不保證在那個內核和這些驅動之外是有效的。

+0

不,「自定義驅動程序」肯定不會影響getaddrinfo的結果。根本沒有內核支持這個東西;這一切都歸結於libc的功能。在Linux和BSD上,libc執行一些解析,創建套接字併發送/解包DNS查詢,然後返回結果。在這些平臺上,除了AF_INET之外的其他任何東西都不可能被返回,除非系統有glibc的黑客版本。 –

+0

是的,我故意混淆有關協議族的一些內容,這些協議族可以通過內核進行動態配置,並用於匹配驅動程序和地址族。而且地址解析完全在用戶空間內,但是我的觀點是,在POSIX的任何列表下,如果AF_ *和PF_完全取決於系統,並且在自定義網絡中提供一個或兩個都是完全合法的。 – caskey