2009-09-10 11 views
6

Getaddrinfo कॉल में कई रोचक झंडे हैं। मैं सोच रहा हूं कि AI_V4MAPPED ध्वज का उद्देश्य क्या है। मुझे लगता है कि किसी भी सिस्टम पर मैं getaddrinfo को :: ffff: n.n.n.n फॉर्म पतों का उत्पादन करने में सक्षम नहीं हूं क्योंकि जब मैं इस ध्वज को सेट करता हूं तो मैं अपेक्षा करता हूं। क्या मैं गलत चीज़ की उम्मीद कर रहा हूं? क्या मैं बग देख रहा हूँ?getaddrinfo में AI_V4MAPPED ध्वज का उद्देश्य क्या है?

कण में, अगर मैं AF_INET6 परिवार के पते के लिए पूछता हूं और AI_V4MAPPED निर्दिष्ट करता हूं तो मुझे मेजबानों के लिए :: ffff: n.n.n.n पते देखने की उम्मीद होगी जिसमें केवल DNS ए (IPv4 पता) रिकॉर्ड होंगे। और मैं आम तौर पर यह भी उम्मीद करता हूं कि अगर मैंने AI_ALL निर्दिष्ट किया है कि मुझे मेजबान का DNS एएएए (आईपीवी 6 पता) रिकॉर्ड और DNS ए रिकॉर्ड :: ffff: n.n.n.n रूप में प्राप्त होगा।

फिर, क्या मैं यहां सभी गलत चीजों की अपेक्षा कर रहा हूं?

मैंने फेडोरा 11 - glibc 2.10.1 और ओएस एक्स 10.4 पर इसका परीक्षण किया है।

उत्तर

6

मैं वास्तव में क्या आप प्राप्त करने के लिए उम्मीद कर रहे हैं, डेबियन लेनी (glibc 2.7) पर मिलता है - एक अपवाद के साथ - अगर मैं AI_ALL बिना AI_V4MAPPED निर्दिष्ट करें, और होस्ट नाम मैं ऊपर देखो CNAME उपलब्ध एक रिकॉर्ड की ओर इंगित करता है, मैं ' उन लोगों को वापस नहीं मिला। यह ठीक काम करता है अगर AI_ALL भी निर्दिष्ट है, या यदि होस्टनाम सीधे एक रिकॉर्ड से जुड़ा हुआ है।

मुझे नहीं पता क्यों - शायद यह एक ग्लिबक बग है?

#include <stdio.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netdb.h> 
#include <arpa/inet.h> 

int main(int argc, char *argv[]) 
{ 
    struct addrinfo hints = { 0 }; 
    struct addrinfo *res, *res_c; 
    int err; 
    char name[INET6_ADDRSTRLEN]; 

    if (argc < 2) 
    { 
     return 1; 
    } 

    hints.ai_family = AF_INET6; 
    hints.ai_flags = AI_V4MAPPED | AI_ALL; 

    err = getaddrinfo(argv[1], NULL, &hints, &res); 

    if (err) 
    { 
     printf("getaddrinfo: %s\n", gai_strerror(err)); 
     return 1; 
    } 

    for (res_c = res; res_c; res_c = res_c->ai_next) 
    { 
     const void *addr; 
     int port; 
     struct protoent *proto; 

     switch (res_c->ai_family) 
     { 
      case AF_INET6: 
       addr = &((struct sockaddr_in6 *)(res_c->ai_addr))->sin6_addr; 
       port = ((struct sockaddr_in6 *)(res_c->ai_addr))->sin6_port; 
       printf("AF_INET6\t"); 
       break; 
      case AF_INET: 
       addr = &((struct sockaddr_in *)(res_c->ai_addr))->sin_addr; 
       port = ((struct sockaddr_in *)(res_c->ai_addr))->sin_port; 
       printf("AF_INET\t"); 
       break; 
      default: 
       addr = NULL; 
       printf("(%d)\t", res_c->ai_family); 
     } 

     proto = getprotobynumber(res_c->ai_protocol); 
     if (proto) 
     { 
      printf("%s\t", proto->p_name); 
     } 
     else 
     { 
      printf("(%d)\t", res_c->ai_protocol); 
     } 

     switch (res_c->ai_socktype) 
     { 
      case SOCK_STREAM: 
       printf("SOCK_STREAM\t"); 
       break; 

      case SOCK_DGRAM: 
       printf("SOCK_DGRAM\t"); 
       break; 

      default: 
       printf("(?socktype?)\t"); 
       break; 
     } 

     if (addr && inet_ntop(res_c->ai_family, addr, name, sizeof name)) 
      printf("addr = %s", name); 

     if (addr) 
      printf(",%d", port); 

     printf("\n"); 
    } 

    return 0; 
} 
+1

मैं इस पर बहुत अधिक शोध कर रहा हूं। Getaddrinfo किसी भी संख्या में बग से पीड़ित प्रतीत होता है, आंशिक रूप से क्योंकि इसमें एएएए अनुरोधों के टूटे हैंडलिंग के लिए बहुत सारे अजीब मामले हैं। – Omnifarious

+0

आप उत्तर वास्तविक जवाब के सबसे नज़दीक हैं, इसलिए आपको उत्तर क्रेडिट प्राप्त होता है। – Omnifarious

+0

AI_ALL के बिना AI_V4MAPPED एक glibc बग है http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=503912 – unixman83

4

मेरे अनुभव में, AI_V4MAPPED मैक ओएस एक्स 10.6 पर काम नहीं करता:

यहाँ मेरी परीक्षण कार्यक्रम है। यदि आप hints.ai_family = AF_INET6 और hints.ai_flags = AI_V4MAPPED प्रदान करते हैं तो यह हमेशा EAI_NONAME, और gai_strerror() प्रिंट करेगा "नोडनाम और न ही सर्वनाम प्रदान किया गया है, या ज्ञात नहीं है"।

यह ओएस एक्स 10.7 पर ठीक से काम करता है।

यहां किसी को मदद करने में यह मदद करता है, भले ही आप फेडोरा पर हों।

संबंधित मुद्दे