2012-07-30 10 views
5

के साथ आईपीवी 4 सॉकेट (sockaddr_in) की तुलना करना मेरे पास एक यूडीपी सर्वर है जिसे ग्राहकों को आईपीवी 4 और आईपीवी 6 पते दोनों पर सेवा देना है। मैंने आईपीवी 4 और आईपीवी 6 क्लाइंट दोनों की सेवा के लिए एक आईपीवी 6 सॉकेट बनाया है।

सर्वर पहले संचार पर क्लाइंट के आईपी एड्रेस स्टोर करता है। यदि यह एक आईपीवी 4 क्लाइंट है तो यह आईपीवी 4 एड्रेस के रूप में स्टोर करता है और यदि यह आईपीवी 6 क्लाइंट है तो सर्वर आईपीवी 6 एड्रेस के रूप में स्टोर करता है। भविष्य के संचार के लिए यह भंडारण की जांच करता है कि क्या यह ग्राहक पहले ही ज्ञात है (संग्रहीत) और फिर तदनुसार कार्य करता है। क्लाइंट पते को संग्रहीत पते से तुलना करने के लिए मैं परिवार प्रकार (AF_INET और AF_INET6) के आधार पर एक memcmp करता हूं।

आईपीवी 6 क्लाइंट के साथ संवाद करते समय सिस्टम सामान्य रूप से काम कर रहा है लेकिन आईपीवी 4 क्लाइंट के साथ संवाद करते समय सिस्टम व्यवहार करता है जैसे कि यह क्लाइंट को कभी नहीं जानता था। डीबगिंग के दौरान मैंने पाया कि आईपीवी 6 के कारण सॉकेट टाइप आईपीवी 4 क्लाइंट के आईपी एड्रेसर्स को आईपीवी 6 मैप किए गए आईपीवी 4 एड्रेस के रूप में आईपीवी 6 में पारिवारिक सेट के साथ प्राप्त किया जाता है। इसे हल करने के लिए मुझे आईपीवी 4 संग्रहीत पता और आईपीवी 6 मैप किए गए पते के बीच तुलना करने की आवश्यकता है। इसके लिए मैं आईपीवी 4 संरचना के sin_addr.s_addr और IP66 संरचना के sin6_addr.in6_u.u6_addr32 का उपयोग कर रहा हूं। कृपया नीचे कोड स्निपेट पाएं।IPV6 सॉकेट (sockaddr_in6)

ipv6_clientdata = (const struct sockaddr_in6 *)&sockStor; 
ipv4_storeddata = (const struct sockaddr_in *)&(_stData[index].clientaddr); 
if((ipv6_clientdata->sin6_port == ipv4_storeddata->sin_port) && 
    (ipv6_clientdata->sin6_addr.in6_u.u6_addr32[3] == ipv4_storeddata->sin_addr.s_addr) 
) 
{ 
    addrfound = true; 
} 

मुझे पता है कि इस विधि IPv4 पता के साथ IPV6 मैप IPv4 पता की तुलना के लिए उचित समाधान है या कोई अन्य बेहतर तरीका है कि क्या करना चाहते हैं।

+0

मैं मानता हूं मैं अभी तक आईपीवी 6 का अधिक अनुभव नहीं है, लेकिन जैसे नहीं होगा 'revfrom' स्रोत पते को 'AF_INET6' के रूप में वापस लौटाता है, भले ही यह एक आईपीवी 6-मैप किए गए आईपीवी 4 पते हो? –

+0

क्षमा करें मैं निम्नलिखित सुविधा का उल्लेख करने के लिए छोड़ दिया/भूल गया। सर्वर को क्लाइंट एड्रेस दो तरीकों से मिलता है। 1) यूडीपी 2 पर ग्राहक के साथ पहले संचार पर) ग्राहक सर्वर पर एक्सएमएल डेटा के रूप में टीसीपी पर अपने यूडीपी कनेक्शन विवरण पोस्ट कर सकता है। इस मामले में ग्राहक केवल आईपीवी 4 पता प्रदान करेगा। –

+3

आपको यह भी जांचने की आवश्यकता है कि पहले 80 बिट शून्य हैं या नहीं और अगले 16 बिट्स पिछले 32 बिट्स की तुलना करने से पहले एक हैं। अन्यथा आप नहीं जानते कि क्या आप आईपीवी 4 के रूप में आईपीवी 4 मैप किए गए हैं। –

उत्तर

2

Joachim Pileborg तर्क के रूप में, आपको इस बारे में परवाह करने की आवश्यकता नहीं है जब आईपीवी 4 पता उसी सॉकेट पर प्राप्त पहले पैकेट से आता है क्योंकि आप एक मैप किए गए आईपीवी 4 पते की तुलना किसी दूसरे से करेंगे। यह केवल इस मामले में है कि आईपीवी 4 पता बाहरी स्रोत से प्राप्त किया गया था जिसे आपको परवाह करना है।

João Augusto के रूप में, आपने यह जांचने के लिए उपेक्षित किया कि आईपीवी 6 पता वास्तव में पिछले 32 बिट्स की तुलना करने से पहले एक आईपीवी 4 मैप किया गया पता है। वहाँ एक मैक्रो IN6_IS_ADDR_V4MAPPED आप यह कर में मदद मिलेगी है:

if (
    IN6_IS_ADDR_V4MAPPED(&(ipv6_clientdata->sin6_addr)) && 
    (ipv6_clientdata->sin6_port == ipv4_storeddata->sin_port) && 
    (ipv6_clientdata->sin6_addr.in6_u.u6_addr32[3] == ipv4_storeddata->sin_addr.s_addr) 
) { 
    addrfound = true; 
} 
संबंधित मुद्दे