Can I bind a TCP socket to a local IPV6 address, then connect it to peer IPV4 address? It seems impossible since an ip packet cannot include ipv4 (destination) address and ipv6 (source) address at the same time.
Can I bind a TCP socket to a local IPV6 address, then connect it to peer IPV4 address?
No, the IP protocol must match for the connection to succeed. The connect call will simply fail, without even sending out any packets.
Related
I have a server where I need to connect. My client is written in Dart, and binds the socket like this:
static Future<RawDatagramSocket> rDgS =
RawDatagramSocket.bind(InternetAddress.anyIPv4, 50943);
Can I use something else to not specify the version of the IP-protocol to make it connect on both IPv4 and IPv6-only networks? I am using UDP sockets.
I have tried both anyIPv4 and andIPv6 using both server IP-addresses (IPv4 and IPv6) since I don't have a DNS hostname for my server. Only anyIPv4 works with IPv4 address.
To accept IPv6 connections, you have to have a IPv6 address. Same for accepting IPv4. Similarly, to connect, you both have to be using the same protocol. IPv4 and IPv6 are not interchangeable.
I need to find out the local IP address on a very old platform which doesn't have getifaddrs(). Lots of people recommend to do this by creating a UDP socket, connect() it to a destination IP and then use getsockname() to find out the local IP address (see here)
Is there a way to make this work on systems that don't have Internet access? AFAIU, for UDP sockets connect() just sets the default destination address for the socket without actually establishing any connection. So can I just use some random destination IP with connect() because it doesn't connect immediately for UDP sockets anyway? I.e. can I just pass 8.8.8.8 as a dummy IP to connect() and getsockname() will still allow me to get the local IP address even if there is no Internet connection?
So I know that a socket address is the combination of an IP address and a port number, but which IP address is used for the socket address? Is it the private or the public IP address, or can it be both but you have to choose one?
A connected socket can have any IP which is local on the machine - but only one at a time. A socket which is not connected (i.e. listening socket in case of TCP) can instead also be bound the catch-all IP (0.0.0.0 for IPv4, :: for IPv6) and thus receive data on all local IP.
Running socket.gethostbyname(socket.gethostname()) will give you the IP address it is using.
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.)
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.
When i use the INADDR_ANY to specify the IP address to bind to socket, which later listens on a port, like so:
sockaddr_in sockAddr;
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(80);
sockAddr.sin_addr.S_un.S_addr = INADDR_ANY; // use default
Will this socket structure allow external, internal, and loopback IP addresses to connect to to me?
I don't want to limit IP addresses that can communicate with me by putting my computer external address(ie: 122.215.214.3) in place of INADDR_ANY because then internal IP's can't connect.
I'm wondering if INADDR_ANY will bind with all 3 of my computer's IP addresses(external,internal,loopback).
When binding a listening socket, INADDR_ANY allows inbound connections on any local IPv4 address that directly belongs to the machine that the listening socket is running on, which includes loopback addresses. However, you cannot bind to an external IP address that is outside of the machine, such as the public IP of a network router. The router would have to be configured to forward incoming connections from the public IP to a private LAN IP that is assigned to the listening machine that it can bind on.