Reputation: 3755
Let's say you have a game server, UDP only, running on a server which has both IPv4 and IPv6 addresses. The server starts up, calls getaddrinfo() to loop through available addresses, and let's say it grabs the IPv6 address. So it creates it's socket on IPv6 and waits for packets from clients.
A client tries to connect, but this time it's using an IPv4 address entered by the user. It creates a IPv4 socket, and tries to connect to the server. Does the difference actually matter? Or does the difference between a IPv4 socket and a IPv6 socket stop at the local machine?
Likewise, if the client has already created, say, a IPv6 socket for use (because getaddrinfo() said it was valid), and then it calls getaddrinfo() to find a server's address, what if it only gets a IPv4 result? I know I can tell getaddrinfo() to only give IPv6 results, but what if the server doesn't have an IPv6 address? Are UDP clients supposed to close and recreate their sockets to match the server address format? Or am I guaranteed to get the address format I ask for?
(I welcome any documentation references that answer these questions. I've been researching for hours but haven't found clear answers to these points yet.)
Upvotes: 1
Views: 2489
Reputation: 73081
By default, the IPv6 UDP socket will send and receive only IPv6 UDP packets, so your IPv4 client would be out of luck.
However, if you are running on a dual-stack machine (and you probably are), you can enable IPv4-mapped IPv6 addresses on the socket, and then you can use that socket to handle both IPv4 and IPv6 UDP traffic. IPv4 packets will show up as coming from a specially-formed IPv6 address (with a form like e.g. "::ffff:192.168.0.5") but otherwise they are handled the same way as any IPv6 UDP client would be.
You can enable IPv4-mapped IPv6 addresses on your socket like this:
int v6OnlyEnabled = 0; // we want v6-only mode disabled, which is to say we want v6-to-v4 compatibility
if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &v6OnlyEnabled, sizeof(v6OnlyEnabled)) != 0) perror("setsockopt");
The other approach would be to create separate IPv4 and IPv6 sockets as necessary (on the client and/or server), but as long as you have a dual-stack networking stack available, the IPv4-mapped IPv6-addresses approach is much easier to work with.
Upvotes: 5