Dual-Stack Soket untuk Aplikasi Winsock IPv6
Untuk mendukung IPv4 dan IPv6 pada Windows XP dengan Service Pack 1 (SP1) dan pada Windows Server 2003, aplikasi harus membuat dua soket, satu soket untuk digunakan dengan IPv4 dan satu soket untuk digunakan dengan IPv6. Kedua soket ini harus ditangani secara terpisah oleh aplikasi.
Windows Vista dan kemudian menawarkan kemampuan untuk membuat soket IPv6 tunggal yang dapat menangani lalu lintas IPv6 dan IPv4. Misalnya, soket mendengarkan TCP untuk IPv6 dibuat, dimasukkan ke dalam mode tumpukan ganda, dan terikat ke port 5001. Soket tumpukan ganda ini dapat menerima koneksi dari klien TCP IPv6 yang terhubung ke port 5001 dan dari klien TCP IPv4 yang terhubung ke port 5001. Fitur ini memungkinkan desain aplikasi yang sangat disederhanakan dan mengurangi overhead sumber daya yang diperlukan dari operasi posting pada dua soket terpisah.
Membuat Soket Dual-Stack
Secara default, soket IPv6 yang dibuat pada Windows Vista dan kemudian hanya beroperasi melalui protokol IPv6. Untuk membuat soket IPv6 ke dalam soket tumpukan ganda, fungsi setsockopt harus dipanggil dengan opsi soket IPV6_V6ONLY untuk mengatur nilai ini ke nol sebelum soket terikat ke alamat IP. Ketika opsi soket IPV6_V6ONLY diatur ke nol, soket yang dibuat untuk keluarga alamat AF_INET6 dapat digunakan untuk mengirim dan menerima paket ke dan dari alamat IPv6 atau alamat yang dipetakan IPv4.
Alamat IP dengan Soket Dual-Stack
Soket tumpukan ganda selalu memerlukan alamat IPv6. Kemampuan untuk berinteraksi dengan alamat IPv4 memerlukan penggunaan format alamat IPv6 yang dipetakan IPv4. Alamat IPv4 apa pun harus diwakili dalam format alamat IPv6 yang dipetakan IPv4 yang memungkinkan aplikasi hanya IPv6 untuk berkomunikasi dengan simpul IPv4. Format alamat IPv6 yang dipetakan IPv4 memungkinkan alamat IPv4 dari simpul IPv4 diwakili sebagai alamat IPv6. Alamat IPv4 dikodekan ke dalam 32 bit berurutan rendah dari alamat IPv6, dan 96 bit pesanan tinggi menyimpan awalan tetap 0:0:0:0:0:FFFF. Format alamat IPv6 yang dipetakan IPv4 ditentukan dalam RFC 4291. Untuk informasi selengkapnya, lihat www.ietf.org/rfc/rfc4291.txt. Makro IN6ADDR_SETV4MAPPED dalam Mstcpip.h dapat digunakan untuk mengonversi alamat IPv4 ke format alamat IPv6 yang dipetakan IPv4 yang diperlukan.
Jika protokol yang mendasar sebenarnya adalah IPv4, maka alamat IPv4 dipetakan ke dalam format alamat IPv6 yang dipetakan IPv4. Artinya, bidang keluarga dalam struktur SOCKADDR menunjukkan AF_INET6, tetapi alamat IPv6 yang dipetakan IPv4 dikodekan dalam struktur alamat IPv6. Untuk soket tumpukan ganda dalam mode mendengarkan, ini berarti bahwa setiap koneksi IPv4 yang diterima akan mengembalikan alamat IPv6 yang dipetakan IPv4. Untuk soket tumpukan ganda yang tersambung ke tujuan IPv4, struktur SOCKADDR yang diteruskan untuk menyambungkan harus alamat IPv6 yang dipetakan IPv4. Aplikasi harus berhati-hati untuk menangani alamat IPv6 yang dipetakan IPv4 ini dengan tepat dan hanya menggunakannya dengan soket tumpukan ganda. Jika alamat IP akan diteruskan ke soket IPv4 reguler, alamat harus berupa alamat IPv4 reguler bukan alamat IPv6 yang dipetakan IPv4.
Potensi Masalah menggunakan Soket Dual-Stack
Jebakan potensial untuk aplikasi adalah mendapatkan alamat IPv6 yang dipetakan IPv4 pada soket tumpukan ganda dan kemudian mencoba menggunakan alamat IP yang dikembalikan pada soket IPv6 saja yang berbeda. Misalnya, fungsi getsockname atau getpeername dapat mengembalikan alamat IPv6 yang dipetakan IPv4 saat digunakan pada soket tumpukan ganda. Jika alamat IPv6 yang dipetakan IPv4 yang dikembalikan kemudian digunakan pada soket berbeda yang tidak diatur ke dual-stack (soket IPv6 saja yang merupakan perilaku default ketika soket dibuat), setiap penggunaan soket hanya IPv6 ini dengan alamat IPv6 yang dipetakan IPv4 akan gagal. Format alamat IPv6 yang dipetakan IPv4 hanya dapat digunakan pada soket tumpukan ganda.
Pada soket datagram tumpukan ganda, jika aplikasi memerlukan fungsi LPFN_WSARECVMSG (WSARecvMsg) untuk mengembalikan informasi paket dalam struktur WSAMSG untuk datagram yang diterima melalui IPv4, maka opsi soket IP_PKTINFO harus diatur ke true pada soket. Jika hanya opsi IPV6_PKTINFO yang diatur ke true pada soket, informasi paket akan diberikan untuk datagram yang diterima melalui IPv6 tetapi mungkin tidak disediakan untuk datagram yang diterima melalui IPv4.
Jika aplikasi mencoba mengatur opsi soket IP_PKTINFO pada soket datagram tumpukan ganda dan IPv4 dinonaktifkan pada sistem, maka fungsi setsockopt akan gagal dan WSAGetLastError akan kembali dengan kesalahan WSAEINVAL. Kesalahan yang sama ini juga dikembalikan oleh fungsi setsockopt sebagai akibat dari kesalahan lain. Jika aplikasi mencoba mengatur opsi soket tingkat IPPROTO_IP pada soket tumpukan ganda dan gagal dengan WSAEINVAL, maka aplikasi harus menentukan apakah IPv4 dinonaktifkan di komputer lokal. Salah satu metode yang dapat digunakan untuk mendeteksi apakah IPv4 diaktifkan atau dinonaktifkan adalah memanggil fungsi soket dengan parameter af yang diatur ke AF_INET untuk mencoba dan membuat soket IPv4. Jika fungsi soket gagal dan WSAGetLastError mengembalikan kesalahan WSAEAFNOSUPPORT, artinya IPv4 tidak diaktifkan. Dalam hal ini, kegagalan fungsi setsockopt saat mencoba mengatur opsi soket IP_PKTINFO dapat diabaikan oleh aplikasi. Jika tidak, kegagalan saat mencoba mengatur opsi soket IP_PKTINFO harus diperlakukan sebagai kesalahan yang tidak terduga.
Untuk soket tumpukan ganda saat mengirim datagram dengan fungsi WSASendMsg dan aplikasi ingin menentukan alamat sumber IP lokal tertentu yang akan digunakan, metode untuk menangani ini tergantung pada alamat IP tujuan. Saat mengirim ke alamat tujuan IPv4 atau alamat tujuan IPv6 yang dipetakan IPv4, salah satu objek data kontrol yang diteruskan dalam struktur WSAMSG yang diarahkan oleh parameter lpMsg harus berisi struktur in_pktinfo yang berisi alamat sumber IPv4 lokal yang akan digunakan untuk pengiriman. Saat mengirim ke alamat tujuan IPv6 yang bukan alamat IPv6 yang dipetakan IPv4, salah satu objek data kontrol yang diteruskan dalam struktur WSAMSG yang diarahkan oleh parameter lpMsg harus berisi struktur in6_pktinfo yang berisi alamat sumber IPv6 lokal untuk digunakan untuk pengiriman.
Topik terkait