Bottle: kein IPv6 Support?

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
uKev
User
Beiträge: 15
Registriert: Mittwoch 9. Dezember 2009, 13:43

Hallo liebe Python-Gemeinde,

ich bin neu hier, habe schon öfter gelesen, aber bisher noch nichts geschrieben. Ich habe nun beschlossen, mich mal etwas näher mit Bottle zu beschäftigen und wollte den internen Webserver auf meinem Server starten.
Beim Binden an meine IPv6 Adresse kam es leider zu einem Fehler.

Kann es sein, dass Bottle noch keinen IPv6 Support hat?
Ist sowas geplant?
Oder habe ich etwas falsch gemacht?

Gemacht habe ich folgendes:

Code: Alles auswählen

run(host='[meine:ip::v6]', port=8080)
Fehler:
File "main.py", line 81, in <module>
run(host='[2001:638:204:10:a00:27ff:fe6f:fb96]', port=8080)
File "/home/kev/bottle/bottle.py", line 923, in run
server.run(app)
File "/home/kev/bottle/bottle.py", line 849, in run
srv = make_server(self.host, self.port, handler)
File "/usr/lib/python3.1/wsgiref/simple_server.py", line 181, in make_server
server = server_class((host, port), handler_class)
File "/usr/lib/python3.1/socketserver.py", line 400, in __init__
self.server_bind()
File "/usr/lib/python3.1/wsgiref/simple_server.py", line 51, in server_bind
HTTPServer.server_bind(self)
File "/usr/lib/python3.1/http/server.py", line 127, in server_bind
socketserver.TCPServer.server_bind(self)
File "/usr/lib/python3.1/socketserver.py", line 411, in server_bind
self.socket.bind(self.server_address)
socket.gaierror: [Errno -2] Name or service not known
Probiert habe ich auch:

Code: Alles auswählen

run(host='meine:ip::v6', port=8080)
Traceback (most recent call last):
File "main.py", line 81, in <module>
run(host='2001:638:204:10:a00:27ff:fe6f:fb96', port=8080)
File "/home/kev/bottle/bottle.py", line 923, in run
server.run(app)
File "/home/kev/bottle/bottle.py", line 849, in run
srv = make_server(self.host, self.port, handler)
File "/usr/lib/python3.1/wsgiref/simple_server.py", line 181, in make_server
server = server_class((host, port), handler_class)
File "/usr/lib/python3.1/socketserver.py", line 400, in __init__
self.server_bind()
File "/usr/lib/python3.1/wsgiref/simple_server.py", line 51, in server_bind
HTTPServer.server_bind(self)
File "/usr/lib/python3.1/http/server.py", line 127, in server_bind
socketserver.TCPServer.server_bind(self)
File "/usr/lib/python3.1/socketserver.py", line 411, in server_bind
self.socket.bind(self.server_address)
socket.gaierror: [Errno -9] Address family for hostname not supported
Mit host='localhost' funktioniert es prima, aber lauscht dann halt nur auf der IPv4 auf loopback.

Gibt es auch die Möglichkeit auf allen Interfaces zu laufen?
Die Doku und die FAQ habe ich durchgelesen und leider nichts dazu gefunden.
Ich bin euch für jeden Hinweis oder Idee dankbar.

Viele Grüße,

Kev
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

Bottle reicht den Host 1 zu 1 an den wsgi-Server weiter. Wenn dieser kein IPv6 kann, kann Bottle das auch nicht. Und laut deinem Traceback sieht es sogar so aus, das deine Socket-Implementierung kein IPv6 kennt.
Bottle: Micro Web Framework + Development Blog
uKev
User
Beiträge: 15
Registriert: Mittwoch 9. Dezember 2009, 13:43

Hi Defnull,

vielen Dank für deine schnelle Antwort.

Laut socket.has_ipv6 habe ich ipv6 Support:

Code: Alles auswählen

$ python3.1
Python 3.1.1+ (r311:74480, Nov  2 2009, 15:45:00) 
[GCC 4.4.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> socket.has_ipv6
True
Gibts noch etwas, das ich testen/ausprobieren kann? Du meinst also, dass es prinzipiell funktionieren sollte?

EDIT: Ich habe gerade mal geschaut, wie socket funktioniert.
Um IPv6 zu nutzen, muss man den Socket explizit mit der address family erzeugen, z.B. so:

Code: Alles auswählen

test = socket.socket(socket.AF_INET6)
test.bind(("meine:ip::v6", 8080))
(kein Fehler)
Und so klappt das dann anscheinend. Muss man das nur noch mit Bottle zum Laufen bekommen.

EDIT2: Ich habe mal weitere Tests durchgeführt und das Problem scheint wohl wirklich zwischen wsgiref und socket zu liegen:

Code: Alles auswählen

python3
Python 3.1.1+ (r311:74480, Nov  2 2009, 15:45:00) 
[GCC 4.4.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from wsgiref.simple_server import make_server, demo_app
>>> httpd = make_server("meine:ip::v6", 8080, demo_app)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.1/wsgiref/simple_server.py", line 181, in make_server
    server = server_class((host, port), handler_class)
  File "/usr/lib/python3.1/socketserver.py", line 400, in __init__
    self.server_bind()
  File "/usr/lib/python3.1/wsgiref/simple_server.py", line 51, in server_bind
    HTTPServer.server_bind(self)
  File "/usr/lib/python3.1/http/server.py", line 127, in server_bind
    socketserver.TCPServer.server_bind(self)
  File "/usr/lib/python3.1/socketserver.py", line 411, in server_bind
    self.socket.bind(self.server_address)
socket.gaierror: [Errno -9] Address family for hostname not supported
EDIT3:
Ich habe jetzt mal das Problem weiter verfolgt und die Ursache ist wohl, dass in /usr/lib/python3.1/socketserver.py die Protokoll-Familie fest einkodiert ist.
In Zeile 386 findet sich:

Code: Alles auswählen

address_family = socket.AF_INET
Wenn man das durch:

Code: Alles auswählen

address_family = socket.AF_INET6
ersetzt, funktioniert es, allerdings dann nur noch für IPv6.
Man müsste irgendwie die address_family anhand der verwendeten server_address festlegen.

Viele Grüße,

Kev
Antworten