IPv6 and Python

"Martin v. Löwis" martin at v.loewis.de
Sat May 3 04:16:50 EDT 2008


> Thanks a lot. I've been able to listen on ::1:21 after having
> installed IPv6 on both Windows and Linux thanks to your suggestions.
> I'd like to ask one more question: is it possible to bind my server on
> both IPv4 and IPv6 addresses (note: I do not use multiple threads or
> processes)?

You can, of course, open two sockets, and bind one for IPv4 and one for
IPv6. If you then want to use a single thread only, you need to use
poll/select, which will return when there is an incoming connection on
either socket. You then accept() the new connection for the respective
listen socket.

There is a notion of "mapped" IPv4 addresses, which allows to have a
single IPv6 server socket accept both IPv4 and IPv6 connections.
How this precisely works depends on the operating system.

On Linux, "mapped" addresses are the default. Open a v6 socket, and
connect to it through a v4 client, and it will just work. For this,
you need to specify the "any" server address, i.e.

py> s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
py> s.bind(('', 1234))
py> s.listen(100)
py> s.accept()
(<socket._socketobject object at 0xb7d90304>, ('::ffff:77.132.228.129',
43491, 0, 0))
py> s.accept()
(<socket._socketobject object at 0xb7d90bc4>, ('2001:6f8:900:a85::2',
40800, 0, 0))

The first connection was from a v4 client; the second connection from
a v6 client. To *disable* mapped addresses, you need to set the
IPV6_V6ONLY socket option to 1.

On Windows XP (including SP2), mapped addresses are not supported.

On Windows Vista, mapped addresses are supported, but you have
to explicitly *enable* a socket for mapped use, by setting
the IPV6_V6ONLY option to 0.

So in short, you should always set the IPV6_V6ONLY to 0, as the
system defaults vary. If that option is not defined in the socket
module, the system does not support mapped sockets.

Unfortunately, there is an exception to the last rule: on Vista,
the option is supported, but Python won't magically know what the
option numeric value is. So on Windows, you need to define
IPV6_V6ONLY yourself (the value is 27), and check whether the
setsockopt call succeeds.

Regards,
Martin



More information about the Python-list mailing list