2012-11-22 7 views
5

मैं एक वेब सर्वर है कि दोनों IPv4 और IPv6 पते पर सुनता है लिखने की कोशिश कर रहा हूँ। हालांकि, मूल रूप से लिखा गया कोड काम नहीं करता था। तब मुझे पता चला कि आईपीवी 6 संरचनाएं आईपीवी 4 और आईपीवी 6 दोनों के लिए काम करती हैं। तो अब मैं आईपीवी 6 संरचनाओं का उपयोग करता हूं, हालांकि केवल आईपीवी 4 पते काम करते हैं। इस पोस्ट में, why can't i bind ipv6 socket to a linklocal address, server.sin6_scope_id = 5; जोड़ने के लिए कहा है जो इतना मैंने वह किया लेकिन यह अभी भी आईपीवी 6 टेलनेट कनेक्शन स्वीकार नहीं करता है। किसी भी मदद की सराहना की जाएगी क्योंकि मैं पूरी तरह से स्टंप हूं।
धन्यवाद!बाध्यकारी सॉकेट संबोधित

मेरे कोड के नीचे है:

void initialize_server(int port, int connections, char* address) 
{ 
     struct sockaddr_in6 socket_struct; 
     /*Creates the socket*/ 
     if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
     { 
       syslog(LOG_ERR, "%s\n", strerror(errno)); 
       exit(EXIT_FAILURE); 
     }/*Ends the socket creation*/ 

     /*Populates the socket address structure*/ 
       socket_struct.sin6_family = AF_INET6; 

     if(address == NULL) 
       socket_struct.sin6_addr=in6addr_any; 
     else 
     { 
       inet_pton(AF_INET6, "fe80::216:3eff:fec3:3c22", (void *)&socket_struct.sin6_addr.s6_addr); 
     } 
     socket_struct.sin6_port =htons(port); 
     socket_struct.sin6_scope_id = 0; 
     if (bind(sock_fd, (struct sockaddr*) &socket_struct, sizeof(socket_struct)) < 0) 
     { 
       syslog(LOG_ERR, "%s\n", strerror(errno)); 
       exit(EXIT_FAILURE); 
     }//Ends the binding. 

     if (listen(sock_fd, connections) <0) 
     { 
       syslog(LOG_ERR, "%s\n", strerror(errno)); 
       exit(EXIT_FAILURE); 
     }//Ends the listening function 

}//ends the initialize server function. 
+0

मुझे पता है कि आईपीवी 6 64-बिट है, इसलिए ipv6 का उपयोग करने वाले सर्वर 64-बिट ऑपरेटिंग सिस्टम पर चल रहे हैं। अभी के लिए ipv4 का उपयोग करें, अभी तक ipv6 का उपयोग कर बहुत सारे मुद्दे हैं। – GiantHornet

+2

@GiantHornet: आईपीवी 6 न तो 32-बिट और न ही 64-बिट है; यह या तो अन्य सिस्टम पर भी चला सकता है। –

+0

@GiantHornet हाँ, मुझे यह ठीक नहीं लगता क्योंकि मेरी उबंटू मशीन i686 है जो 32-बिट है और इसमें आईपीवी 6 पता – tpar44

उत्तर

7

आप AF_INET परिवार में एक सॉकेट बना रहे हैं, लेकिन फिर AF_INET6 परिवार में एक पते पर बाध्य करने के लिए कोशिश कर रहा। socket() पर अपने कॉल में AF_INET6 का उपयोग करने के लिए स्विच करें।

+0

संकेत के लिए धन्यवाद लेकिन यह अभी भी काम नहीं करता है ... – tpar44

+0

उस बदलाव को बनाने से यह मेरे लिए काम कर रहा है। – qqx

+0

सिर्फ जिज्ञासा आप 'टेलनेट fe80 :: 216 का उपयोग से बाहर: 3eff: fec3: 3c22% eth0 8080' यह परीक्षण करने के लिए? – tpar44

6

कह रही है "server.sin6_scope_id = 5," मनमाने ढंग से है। मैंने थोड़ी देर के साथ लड़ा और पाया कि आपको वास्तविक इंटरफ़ेस के वास्तविक दायरे का उपयोग करने की आवश्यकता है जिसे आप बांधना चाहते हैं। यह एक अस्पष्ट लेकिन उपयोगी छोटे समारोह के साथ पाया जा सकता है।

#include <net/if.h> 
server.sin6_scope_id=if_nametoindex("eth0"); 
बेशक

, एक विशेष एडाप्टर के लिए यह हार्डकोड बुरा, अदूरदर्शा कोडन है। एक और पूरा समाधान उन सभी के माध्यम से लूप करना है और आपके द्वारा बाध्यकारी आईपी पते पर मेल खाना है। निम्नलिखित में यह सही नहीं है कि यह गैर-कैनोलिक पतों और एक ही आईपी के साथ दो एडेप्टर जैसे quirks के लिए जिम्मेदार नहीं है, लेकिन इसके अलावा, यह नमूना समारोह महान काम करता है और आपको शुरू करना चाहिए।

#include <string.h> // strcmp 
#include <net/if.h> // if_nametoindex() 
#include <ifaddrs.h> // getifaddrs() 
#include <netdb.h> // NI_ constants 

// returns 0 on error 
unsigned getScopeForIp(const char *ip){ 
    struct ifaddrs *addrs; 
    char ipAddress[NI_MAXHOST]; 
    unsigned scope=0; 
    // walk over the list of all interface addresses 
    getifaddrs(&addrs); 
    for(ifaddrs *addr=addrs;addr;addr=addr->ifa_next){ 
     if (addr->ifa_addr && addr->ifa_addr->sa_family==AF_INET6){ // only interested in ipv6 ones 
      getnameinfo(addr->ifa_addr,sizeof(struct sockaddr_in6),ipAddress,sizeof(ipAddress),NULL,0,NI_NUMERICHOST); 
      // result actually contains the interface name, so strip it 
      for(int i=0;ipAddress[i];i++){ 
       if(ipAddress[i]=='%'){ 
        ipAddress[i]='\0'; 
        break; 
       } 
      } 
      // if the ip matches, convert the interface name to a scope index 
      if(strcmp(ipAddress,ip)==0){ 
       scope=if_nametoindex(addr->ifa_name); 
       break; 
      } 
     } 
    } 
    freeifaddrs(addrs); 
    return scope; 
} 
संबंधित मुद्दे