2011-08-26 20 views
16

के लिए पसंदीदा आईपीवी 6 स्रोत पता की पहचान करना यदि आपके पास एक आईपीवी 6 सक्षम होस्ट है जिसमें एक से अधिक वैश्विक-स्कोप पता हैं, तो आप bind() के लिए पसंदीदा पते को प्रोग्रामेटिक रूप से कैसे पहचान सकते हैं?एडाप्टर

उदाहरण पता सूची:

eth0  Link encap:Ethernet HWaddr 00:14:5e:bd:6d:da 
      inet addr:10.6.28.31 Bcast:10.6.28.255 Mask:255.255.255.0 
      inet6 addr: 2002:dce8:d28e:0:214:5eff:febd:6dda/64 Scope:Global 
      inet6 addr: fe80::214:5eff:febd:6dda/64 Scope:Link 
      inet6 addr: 2002:dce8:d28e::31/64 Scope:Global 
      UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 

सोलारिस पर आप एक इंटरफेस ध्वज के साथ एक पसंदीदा पता इंगित कर सकते हैं और यह SIOCGLIFCONF के माध्यम से प्रोग्राम के रूप में उपलब्ध है: इंटरफ़ेस सूची में सूचीबद्ध के रूप में

/usr/include/net/if.h: 
#define IFF_PREFERRED 0x0400000000 /* Prefer as source address */ 

:

eri0: flags=2104841<UP,RUNNING,MULTICAST,DHCP,ROUTER,IPv6> mtu 1500 index 2 
     inet6 fe80::203:baff:fe4e:6cc8/10 
eri0:1: flags=402100841<UP,RUNNING,MULTICAST,ROUTER,IPv6,PREFERRED> mtu 1500 index 2 
     inet6 2002:dce8:d28e::36/64 

यह ओएसएक्स के लिए पोर्टेबल नहीं है, लिनक्स, फ्रीबीएसडी, या विंडोज हालांकि। विंडोज़ को आसान छोड़ दिया गया है, हालांकि यह प्रशासक परिप्रेक्ष्य से यूयूआईडी आधारित एडाप्टर नाम (विंडोज संस्करण के आधार पर) पूरी तरह से बेकार है।

लिनक्स this article के लिए विवरण पैरामीटर preferred_lft, जहां lft "जीवनकाल" के लिए छोटा है, कर्नेल द्वारा चयन प्रक्रिया को वज़न में बदलने के लिए बदला जा सकता है। यह सेटिंग SIOCGIFCONF या getifaddrs() के परिणामों में आसानी से उपलब्ध नहीं दिखाई देती है।

तो मैं eth0, eri0, या जो भी उपलब्ध इंटरफ़ेस नाम से बांधना चाहता हूं। विकल्प थोड़ा सा स्टार्क हैं:

  1. एकाधिक इंटरफेस को हल करने वाले एडाप्टर नामों पर विफल। मैं मल्टीकास्ट ट्रांसपोर्ट (OpenPGM) को संभालने के लिए इस दृष्टिकोण को लेता हूं क्योंकि प्रोटोकॉल में केवल एक ही भेजना पता होना चाहिए।
  2. सबकुछ से बांधें। यह एक पुलिस है और उपयोगकर्ताओं के लिए अप्रत्याशित होगा।
  3. SO_BINDTODEVICE के साथ एडाप्टर से बांधें। इसके लिए लिनक्स पर CAP_NET_RAW सिस्टम क्षमता की आवश्यकता है जो प्रशासकों के लिए काफी बोझिल ओवरहेड हो सकता है।
  4. एडाप्टर पर पहले आईपीवी 6 इंटरफ़ेस से जुड़ें। आदेश पूरी तरह से फर्जी हो जाता है।
  5. अंतिम इंटरफ़ेस से जुड़ें। David Croft के आलेख का तात्पर्य है कि लिनक्स यह करता है, लेकिन यह थोड़ा सा भीड़ है।
  6. प्रत्येक इंटरफ़ेस पर गणना करें और प्रत्येक के लिए स्पष्ट रूप से एक नया सॉकेट बनाएं।

विकल्प # 6 के साथ मैं उम्मीद करता हूं कि आप आमतौर पर चालाक हो सकते हैं और दृष्टिकोण ले सकते हैं कि यदि केवल एक लिंक-स्थानीय स्कोप पता उपलब्ध हो, तो अन्यथा उपलब्ध वैश्विक लिंक स्कोप पते से जुड़ें।

जब एक और मेजबान तो RFC 3484 से कनेक्ट करने के लिए इस्तेमाल किया जा सकता है, लेकिन जैसा कि आप देख सकते हैं सभी विकल्प गंतव्य पता मिलान पर निर्भर हैं:

  1. एक ही पते को प्राथमिकता दें। (यानी गंतव्य स्थानीय मशीन है)
  2. उचित दायरे को पसंद करें। (यानी गंतव्य के साथ साझा किया गया सबसे छोटा गुंजाइश)
  3. बहिष्कृत पते से बचें।
  4. घर के पते पसंद करते हैं। आउटगोइंग इंटरफ़ेस पसंद करें। (अर्थात।
  5. मिलान लेबल को पसंद करते हुए हम में इंटरफ़ेस पर एक पता पसंद करते हैं।
  6. सार्वजनिक पते पसंद करते हैं।
  7. सबसे लंबे समय तक मिलान करने वाले उपसर्ग का उपयोग करें।

कुछ परिस्थितियों में हम यहां # 7 का उपयोग कर सकते हैं, लेकिन वैश्विक-स्कोप इंटरफेस दोनों के ऊपर इंटरफ़ेस उदाहरण में 64-बिट उपसर्ग लंबाई है।

RFC 3484 निम्नलिखित प्रासंगिक लाइनों है:

आईपीवी 6 को संबोधित वास्तुकला 5 कई यूनिकास्ट
पतों इंटरफेस को सौंपा जा करने के लिए अनुमति देता है। इन पते में
विभिन्न पहुंच क्षमता स्कॉप्स (लिंक-स्थानीय, साइट-स्थानीय, या वैश्विक) हो सकते हैं।
ये पते भी "पसंदीदा" या "बहिष्कृत" 6 हो सकते हैं।

लिंक RFC 2462 करने जा रहा है, ठीक उसी प्रकार का विस्तार:

पसंदीदा पते - एक पते एक अंतरफलक जिसका उपयोग ऊपरी परत प्रोटोकॉल द्वारा अप्रतिबंधित है को सौंपा। पसंदीदा पते को इंटरफ़ेस से (या) इंटरफेस से भेजे गए पैकेट के स्रोत (या गंतव्य) पते के रूप में उपयोग किया जा सकता है।

लेकिन प्रोग्रामेटिक रूप से इस विवरण को हासिल करने के लिए कोई तरीका नहीं है।

Win32 API के लिए प्रॉप्स जो एक ioctl SIO_ADDRESS_LIST_SORT का खुलासा करता है जो डेवलपर को न केवल आरएफसी 3484 सॉर्टिंग का उपयोग करने की अनुमति देता है बल्कि किसी भी सिस्टम व्यवस्थापक को ओवरराइड करने पर विचार करता है। लिनक्स में /etc/gai.conf है जो getaddrinfo() में आरएफसी 3484 सॉर्टिंग के लिए उपयोग किया जाता है लेकिन सॉर्टिंग तक सीधे पहुंचने के लिए कोई एपीआई नहीं है। सोलारिस में ipaddrsel कमांड है। ओएसएक्स 10.7 में ip6addrctl जोड़कर फ्रीबीएसडी का पालन कर रहा है।

संपादित करें: आरएफसी 3484 सॉर्टिंग की सहायता से कुछ चिंताएं सूचीबद्ध हैं और इस अतिरिक्त IETF मसौदा दस्तावेज में करने के लिए भेजा:

http://tools.ietf.org/html/draft-axu-addr-sel-01

सोलारिस, उदाहरण के लिए, बनाता है प्रत्येक नए के लिए नया उपनाम-इंटरफेस
पता एक भौतिक इंटरफ़ेस को सौंपा गया पता। तो if_index भी
उस प्लेटफॉर्म पर
पर स्रोत पता विशिष्ट रूटिंग तालिका की विशिष्ट पहचान करने के लिए उपयोग किया जा सकता है। अन्य ऑपरेटिंग सिस्टम एक ही तरीके से काम नहीं करते हैं।

लेखक, प्रत्येक अतिरिक्त आईपीवी 6 इंटरफ़ेस एक नया उपनाम देने की सोलारिस के दृष्टिकोण पसंद करती है ताकि eri0 लिंक स्थानीय गुंजाइश पता बन जाएगा और eri0:1 या eri0:2, आदि, एक वैश्विक दायरे पते का उपयोग करना निर्दिष्ट किया जाना चाहिए ।

स्पष्ट रूप से एक अच्छा विचार है कि कोई भी कुछ समय के लिए अन्य ओएस परिवर्तन देखने की उम्मीद नहीं कर सका।

+0

ओएस को आपके लिए चुनने के बजाय आप एक विशिष्ट पते से जुड़ना चाहते हैं? –

+1

बहु-एनआईसी वातावरण में सैंडर परिनियोजन, उदाहरण के लिए आपके पास इंटरनेट, डीएमजेड, इंट्रानेट हो सकता है, या कुछ ट्रैफिक प्रवाह, जैसे कि कच्चे इनकमिंग डेटा, संसाधित डेटा और क्लाइंट यातायात के लिए समर्पित नेटवर्क हो सकते हैं। –

+0

मैं समझता हूं। आम तौर पर मैं यह सुनिश्चित करने का प्रयास करता हूं कि डिफ़ॉल्ट व्यवहार काम करता है, उदाहरण के लिए आंतरिक संचार के लिए वैश्विक पते और आंतरिक एनआईसी के लिए यूएलए का उपयोग करके, ताकि सबसे लंबा उपसर्ग मिलान काम करता है, लेकिन यह हमेशा संभव नहीं होता है। और यह मल्टीकास्ट गंतव्य पर भेजते समय काम नहीं करता है क्योंकि यूएलए का हमेशा लंबा मिलान होता है। कॉन्फ़िगरेशन फ़ाइल में बाध्य करने के लिए स्रोत पता निर्दिष्ट करना एक विकल्प है .. –

उत्तर

2

मुझे यकीन है कि इस दिशा आप की मांग कर रहे हैं में है, लेकिन नहीं कर रहा हूँ ...

iproute बंडल के ip कोड (ip/ipaddress.c) लिनक्स के तहत में आसपास poking पता चलता है कि ip आदेश की तरह इंटरफ़ेस झंडे अप खोदता primary और secondarystruct ifaddrmsg से सदस्य, ifa_flags सदस्य। ifaddmsgstruct nlmsghdr के माध्यम से अधिग्रहण किया जाता है जिसे man 7 netlink में प्रलेखित किया गया है, और sendmsg और recvmsg कर्नेल के साथ बातचीत के माध्यम से उपयोग किया जाता है, जो समग्र रूप से शाही दर्द की तरह लगता है लेकिन यह कम से कम प्रोग्रामेटिक है। क्या प्राथमिक और माध्यमिक उपयोगी होने के लिए पर्याप्त होगा एक अलग सवाल है।

+1

आखिरकार खरगोश छेद के नीचे, एक 'RTM_GETADDR' अनुरोध नेटलिंक पर भेजा जा सकता है ताकि आईपीवी 6 के लिए पते' IFA_CACHEINFO' के साथ पते की सूची लौटा दी जा सके जिसमें पैरामीटर 'ifa_preferred' शामिल है, जो शून्य है, पसंदीदा नहीं है। –

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