I have a python application that needs to select a specific local source address for IPv6 connections but can use the "any" 0.0.0.0 for IPv4 connections. But the application is using a host name in socket.connect((host, port))
to allow socket.connect()
to do the address lookup from name.
So how do I bind both the specific IPv6 source address and the IPv4 "any" address to the local socket given that I don't know before socket.connect()
is called whether an IPv4 address or an IPv6 address will result from the name lookup?
Right now I am handling it with an exception on socket.EAI_ADDRFAMILY
as such:
try:
sock.bind(("2601:a2a0:a0aa:1d00:aeaa:aaff:aa6c:aaab",0))
sock.connect((host, port))
except socket.gaierror, e:
if e[0] == socket.EAI_ADDRFAMILY:
sock.bind(("0.0.0.0",0))
sock.connect((host, port))
But of course there is no guarantee that the socket.connect()
in the exception handler will resolve host to an IPv4 address just because a previous socket.connect()
did.
There must be a better way. I suspect it's going to be that I have to implement the address lookup and selection myself and pass an address, not a name to socket.connect()
. That way I will know when I am doing my local address binding whether socket.connect()
will be using IPv4 or IPv6. But it seems silly for me to have to re-implement the name resolution and selection that socket.connect()
already does.