2011-09-19 3 views
11

GPS 및 기타 측지 센서를 모니터링하는 널리 배포 된 오픈 소스 서비스 데몬 인 GPSD를 유지 관리합니다. 이것은 IPv4와 IPv6 모두에서 포트 2947의 클라이언트 응용 프로그램 연결을 수신 대기합니다. 보안 및 개인 정보 보호를 위해 일반적으로 루프백 주소에서만 수신하지만 어떤 주소에서 수신 대기하도록하는 데몬에 -G 옵션이 있습니다.C 소켓 API를 사용하여 모든 IPV6 주소를 수신하는 방법

문제 : -G 옵션은 IPv4에서 작동하지만 IPv6로 작동시키는 방법을 알아낼 수 없습니다. 다양한 자습서 예제를 기반으로 작동해야하는 메서드는 주소가 이미 사용 중임을 나타내는 오류를 대신 생성합니다. IPv6 네트워크 프로그래밍 경험이있는 사람들로부터이 문제를 해결할 수있는 도움을 찾고 있습니다. 쉽게 NETSTAT -l가 확인 될 때 ​​

관련 코드는 http://git.berlios.de/cgi-bin/gitweb.cgi?p=gpsd;a=blob;f=gpsd.c;h=ee2156caf03ca23405f57f3e04e9ef306a75686f;hb=HEAD

이 코드는 IPv4의에서 -G 및 비 -G 두 경우 모두 올바르게 작동이다.

이제 "case AF_INET6 :"다음에 398 행을 둘러보십시오. listen_global 옵션은 -G에 의해 설정됩니다. false이면 코드가 성공합니다. 같이 읽고 알 수없는 기여를 승계하여 다음과 같은 의견은, 현재이 :

나는 고개를 한 다양한 튜토리얼 예에 따르면
/* 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에 매핑됩니다. 그러나 이는 IPv6 소켓의 설정을 변경하지 않고 IPv4 소켓과 동일한 포트의 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을위한 플랫폼에서 기본값이 없습니다 - 기본적으로 당신은 항상 필요 의미 다른 플랫폼에 대해 신경 쓰지 않는 한 신경 써서 명시 적으로 켜거나 끕니다. 리눅스는 임의의 리눅스 시스템의 포함 파일의 모습에서 ... 윈도우는 기본적으로에 나뭇잎, 기본적으로

+1

리눅스 디폴트는 실제로 sysctl에서 나온다. 따라서 모든 곳에서 기본값을 신뢰할 수는 없습니다. 그러나 sysadmin이 변경하지 않으면 기본적으로 off로 설정됩니다. (가장 적합한 기본 IMO가 꺼짐). –

+1

당신의 대답은 정확하며 나의 버그는 수정되었습니다. 고맙습니다. – ESR

1

떨어져 그것을 잎, 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가 이미 "any"주소를 듣고 있다면 IPv6도 할 수 없다는 힌트를 발견했다. 아마도 그것이 당신을 물어 뜯는 것입니다.

+0

진단의 두 번째 부분이 정확합니다 (Dietrich Epp의 답변 참조). 나는 첫 번째 부분에 대해서도 당신이 옳다고 생각합니다. – ESR

관련 문제