2011-09-19 86 views
11

我維護GPSD,這是一種廣泛部署的開源服務守護程序,可監視GPS和其他大地測量傳感器。它在IPv4和IPv6上偵聽端口2947上的客戶端應用程序連接。爲了安全和隱私,它通常只監聽環回地址,但守護進程有一個-G選項,用於監聽任何地址。如何使用C套接字監聽所有IPV6地址API

問題:-G選項適用於IPv4,但我無法弄清楚如何使它適用於IPv6。基於各種教程實例應該工作的方法不是,反而產生一個提示地址已被使用的錯誤。我正在尋求幫助來解決這個問題,從那些經驗豐富的IPv6網絡編程人員。

相關的代碼是http://git.berlios.de/cgi-bin/gitweb.cgi?p=gpsd;a=blob;f=gpsd.c;h=ee2156caf03ca23405f57f3e04e9ef306a75686f;hb=HEAD

這段代碼在IPv4的下兩個-G和非-G情況下正常工作,因爲很容易用netstat -l驗證。

現在在「case AF_INET6:」之後查看第398行。 listen_global選項由-G設置;當錯誤時,代碼成功。這裏目前是下面的註釋,從一個默默無聞的貢獻者繼承,上面寫着這樣的:

/* else */ 
     /* BAD: sat.sa_in6.sin6_addr = in6addr_any; 
    * the simple assignment will not work (except as an initializer) 
    * because sin6_addr is an array not a simple type 
    * we could do something like this: 
    * memcpy(sat.sa_in6.sin6_addr, in6addr_any, sizeof(sin6_addr)); 
    * BUT, all zeros is IPv6 wildcard, and we just zeroed the array 
    * so really nothing to do here 
    */ 

據我已經看過了各種實例教程,分配「sat.sa_in6.sin6_addr = IN6ADDR_ANY;」是(儘管評論)是正確的,並且它編譯。但是,使用-G啓動失敗,聲稱監聽地址已被使用。

賦值「sat.sa_in6.sin6_addr = in6addr_any;」名義上在這裏正確嗎?還有什麼,如果有的話,我是否錯過了?

+0

您是否嘗試過守護進程? – jpalecek

回答

19

該地址已被使用的原因是因爲在許多IPv6網絡堆棧上,默認情況下IPv6套接字將同時監聽IPv4和IPv6。 IPv4連接將被透明處理並映射到subset of the IPv6 space。但是,這意味着您無法綁定到與IPv4套接字相同的端口上的IPv6套接字,而無需更改IPv6套接字上的設置。合理?

只是這樣做你的電話之前,bind(這是從我的一個項目採取):

int on = 1; 
if (addr->sa_family == AF_INET6) { 
    r = setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)); 
    if (r) 
     /* error */ 
} 

不幸的是,對於IPV6_V6ONLY跨平臺沒有默認值 - 這基本上意味着你總是需要除非你不關心其他平臺,否則明確地打開或關閉它。 Linux的離開它關閉默認情況下Windows離開它在默認情況下...

+1

Linux默認實際來自sysctl。所以你不能依靠那裏的默認。但是,如果系統管理員沒有改變它,它默認關閉。 (off是IMO最合理的默認設置)。 –

+1

您的回答是正確的,我的錯誤已修復。謝謝。 – ESR

1

從隨機Linux系統的包含文件一看,in6addr_any聲明,像這樣:

extern const struct in6_addr in6addr_any;  /* :: */ 
extern const struct in6_addr in6addr_loopback; /* ::1 */ 
#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } } 

所以,也許親近INIT陣列混淆了在GPSD源中留下該評論的人。實際的類型顯然是struct in6_addr,這是可分配的。

我看了一下,發現一些暗示,如果IPv4已經在監聽「任何」地址,IPv6也不能。也許這就是你咬的東西。

+0

您的診斷的第二部分是正確的(請參閱Dietrich Epp的回覆),我懷疑您對第一部分也是正確的。 – ESR