IPv6 and Python

  • Thread starter Giampaolo Rodola'
  • Start date
G

Giampaolo Rodola'

I'm not sure if this is a question about python programming, system
administration or sockets in general...
I have the FTP server in my signature to which I'd want to add IPv6
support.
My hosting company provides me a common IPv4 address.
I'd like to set up my workstation (Windows XP or Linux Debian, doesn't
really matter) to temporarily use IPv6 for trying to add such feature
to my library (I work on both Windows XP and Linux).
Could someone point me to some resources describing how could I do
that?


Thanks in advance.


--- Giampaolo
http://code.google.com/p/pyftpdlib
 
M

Mike Driscoll

I'm not sure if this is a question about python programming, system
administration or sockets in general...
I have the FTP server in my signature to which I'd want to add IPv6
support.
My hosting company provides me a common IPv4 address.
I'd like to set up my workstation (Windows XP or Linux Debian, doesn't
really matter) to temporarily use IPv6 for trying to add such feature
to my library (I work on both Windows XP and Linux).
Could someone point me to some resources describing how could I do
that?

Thanks in advance.

--- Giampaolohttp://code.google.com/p/pyftpdlib

Quote: "The individual computer systems must be upgraded to support
IPv6 (for example, on Windows XP and Server 2003 systems, IPv6 must be
installed as a Network Component via the Network Connections
Properties dialog box) and your routers must be upgraded to support
IPv6 protocols along with IPv4."

See http://articles.techrepublic.com.com/5100-10878_11-5727015.html

Python's socket module also talks about IPv6 calls here:
http://docs.python.org/lib/module-socket.html

I've never messed with this, so good luck!

Mike
 
M

Martin v. Löwis

My hosting company provides me a common IPv4 address.
I'd like to set up my workstation (Windows XP or Linux Debian, doesn't
really matter) to temporarily use IPv6 for trying to add such feature
to my library (I work on both Windows XP and Linux).
Could someone point me to some resources describing how could I do
that?

Information is spread widely. If you really want resources, I recommend
to google for them; there are various IPv6 howtos.

Here is how I would do it:

On Linux, "modprobe ipv6", then "ifconfig". This should display the
loopback adapter, with the address "::1". You should then be able to
listen on that address, and connect to it.

On Windows (XP SP2), "netsh int ipv6 install". Again, you should be able
to use IPv6 loopback afterwards.

If you want true connectivity to the global IPv6 internet, I recommend
SixXS (http://www.sixxs.net/). You can setup a tunnel to the IPv6 net
through your IPv4 POP, using a close IPv6 POP who participates in SixXS.
To set up the tunnel, you then use aiccu, which works really well for
me (and is packaged conveniently as a Debian package).

Regards,
Martin
 
C

Christian Heimes

Giampaolo said:
I'm not sure if this is a question about python programming, system
administration or sockets in general...
I have the FTP server in my signature to which I'd want to add IPv6
support.
My hosting company provides me a common IPv4 address.
I'd like to set up my workstation (Windows XP or Linux Debian, doesn't
really matter) to temporarily use IPv6 for trying to add such feature
to my library (I work on both Windows XP and Linux).
Could someone point me to some resources describing how could I do
that?

Python supports IPv6 out of the box if the underlying OS supports it,
too. You just have to use AF_INET6 instead of AF_INET:

import socket
sock = socket.socket(sock.AF_INET6, socket.AF_STREAM) # IPv6
sock.bind(("::1", 21)) # bind to IPv6 localhost

That's it.

Christian
 
G

Giampaolo Rodola'

Information is spread widely. If you really want resources, I recommend
to google for them; there are various IPv6 howtos.

Here is how I would do it:

On Linux, "modprobe ipv6", then "ifconfig". This should display the
loopback adapter, with the address "::1". You should then be able to
listen on that address, and connect to it.

On Windows (XP SP2), "netsh int ipv6 install". Again, you should be able
to use IPv6 loopback afterwards.

If you want true connectivity to the global IPv6 internet, I recommend
SixXS (http://www.sixxs.net/). You can setup a tunnel to the IPv6 net
through your IPv4 POP, using a close IPv6 POP who participates in SixXS.
To set up the tunnel, you then use aiccu, which works really well for
me (and is packaged conveniently as a Debian package).

Regards,
Martin

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)?


---- Giampaolo
http://code.google.com/p/pyftpdlib
 
R

Roy Smith

"Giampaolo Rodola' said:
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)?

In theory, you should be able to bind your server socket to an IPv6 port
and have it accept connections from both IPv4 and IPV6 clients. The v4
connections will show up as IPv4-mapped IPv6 addresses (i.e. with a
::ffff/96 prefix). In practice, support for this is spotty. The Wikipedia
IPv4_mapped_address article claims, for example, that no windows OS prior
to vista supports it.

In the application I work on, we've avoided this. We just listen on two
separate sockets (one for each address family). We wrote a DualSocket
class which manages the two underlying single-protocol sockets and makes
them appear to be a single dual-protocol socket. It was a lot of user code
to write, compared with using the mapped address mechanism, but at least
it's portable to every OS we've seen that support IPv6.

You don't need multi-threading to handle multiple sockets. In our
implementation, for example, we use select() in a single thread to
multiplex the two.
 
M

Martin v. Löwis

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
 
G

Giampaolo Rodola'

In the application I work on, we've avoided this.  We just listen on two
separate sockets (one for each address family).  We wrote a DualSocket
class which manages the two underlying single-protocol sockets and makes
them appear to be a single dual-protocol socket.  It was a lot of user code
to write, compared with using the mapped address mechanism, but at least
it's portable to every OS we've seen that support IPv6.

You don't need multi-threading to handle multiple sockets.  In our
implementation, for example, we use select() in a single thread to
multiplex the two.

I would be very interested in taking a look at how you implemented
that part of code. Would it be possible?
For now I wrote this and it seems to work just fine.
Any advice about it?



class FTPServer(asyncore.dispatcher):

def __init__(self, address, handler):
"""Initiate the FTP server opening listening on address.

- (tuple) address: the ip:port pair on which to listen
for ftp data connections.
- (classobj) handler: the handler class to use.
"""
asyncore.dispatcher.__init__(self)
self.handler = handler
host, port = address
for res in socket.getaddrinfo(host, port, 0,
socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res
try:
self.create_socket(af, socket.SOCK_STREAM)
except socket.error, msg:
if self.socket:
self.socket.close()
self.socket = None
continue
break
if not self.socket:
raise socket.error, msg
self.address_family = af

if os.name not in ('nt', 'ce'):
self.set_reuse_addr()
self.bind(address)
self.listen(5)

def handle_accept(self):
sock_obj, addr = self.accept()
log("[]%s:%s Connected." %addr[0:2])
handler = self.handler(sock_obj, self)


--- Giampaolo
http://code.google.com/p/pyftpdlib/
 
R

Roy Smith

In article "Giampaolo Rodola' said:
I would be very interested in taking a look at how you implemented
that part of code. Would it be possible?

Sadly, no. It's proprietary code. But, it's really not that complicated
to reconstruct, once you know the basic idea. You have a DualSocket class
whose constructor creates two sockets. It exposes (roughly) the same
interface as a socket object, but decides which underlying
protocol-specific socket to delegate to based on the address family of the
sockaddr you give it.

Oh, yeah, this was done in C++, but there's nothing really that's language
specific in the implementation.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top