I am attempting to use an IPv6 socket to connect to an IPv4 address using an IPv4 mapped IPv6 address, on linux (debian-lenny-64 2.6.26-2-amd64)
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, void **argv)
{
struct addrinfo *sa;
struct addrinfo *ra;
int err = getaddrinfo("2001:DB8::2", 0, 0, &sa);
int fd = socket(sa->ai_family, SOCK_DGRAM, 0);
int v6only = 0;
err = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&v6only, sizeof(v6only));
err = bind(fd, sa->ai_addr, sa->ai_addrlen);
err = getaddrinfo("::ffff:192.168.0.1", "9", 0, &ra);
// err = getaddrinfo("2001:DB8::1", "9", 0, &ra);
// err = getaddrinfo("::ffff:127.0.0.1", "9", 0, &ra);
err = connect(fd, (struct sockaddr *)ra->ai_addr, sizeof(struct sockaddr_in6));
}
(I've removed error testing from the pasted code)
2001:DB8::2 and 192.168.0.2 are local addresses (both on the same interface).
2001:DB8::1 and 192.168.0.1 are the remote addresses (both on the same interface).
I change the remote address for the connect call and get the following:
- connect to ::ffff:127.0.0.1 success (localhost)
- connect to 2001:DB8::1 success (remote IPv6 address)
- connect to ::ffff:192.168.0.2 success (local IPv4 address)
- connect to ::ffff:192.168.0.1 failure (22 Invalid argument - remote IPv4)
If I change to doing IPv4 connects then the connects also work.
I think there must be an issue with routing somewhere but I'm at a loss to work out what I need to change.
Firstly should I in theory be able to do this?
Any ideas what is going wrong?
bind()
call? – Celadabind()
to an IPv4 address when youconnect()
to an IPv4 address, andbind()
to an IPv6 address when youconnect()
to an IPv6 address, then I suppose it will work. – Celada::ffff:192.168.0.2
is the address of the socket. So that makes sense. Some internal magic means that 127.0.0.1 and local IPv4 addresses will work when you bind to IPv6. Once you attempt to go to a remote IPv4 address using an IPv6 socket you cannot bind to a local IPv6 address. Thanks for the help. – superrobot