SlideShare ist ein Scribd-Unternehmen logo
1 von 22
Downloaden Sie, um offline zu lesen
Socket-Programmierung mit IPv6

           Christian Kauhaus


            gocept gmbh & co. kg


   PyCon DE Leipzig, 7. Oktober 2011




                          Socket-Programmierung mit IPv6 · Christian Kauhaus · 1
Übersicht

1 Einleitung
.


2 Aktive Socketverbindungen (Clients)
.


3 Passive Socketverbindungen (Server)
.


4 IP-Adressen
.

5 Zusammenfassung
.




                                 Socket-Programmierung mit IPv6 · Christian Kauhaus · 2
Einleitung
                                              Anti-Motivation


Brauche ich IPv6-Socketprogrammierung?
In der Regel nicht.

IPv6-Support umsonst durch:
 • Bibliotheken (urllib etc.)
 • Frameworks (Twisted etc.)
 • vorgelagerter Server (nginx etc.)


Aber wenn ich es doch mal brauche..?


                                 Socket-Programmierung mit IPv6 · Christian Kauhaus · 3
Durchgehendes Beispiel
                                  Christians DATE-Protokoll

Simples Protokoll, um das aktuelle Datum abzufragen
 • Client sagt: DATE
 • Server sagt: DATE YYYY-MM-DD

class DateHandler(socketserver.BaseRequestHandler):

   def handle(self):
       if self.request.recv(1024).strip() == 'DATE':
           self.request.send('DATE %srn' %
               datetime.date.today())
       else:
           self.request.send('ERRORrn')

class DateSocketServer(socketserver.ThreadingMixIn,
                       socketserver.TCPServer):
    allow_reuse_address = True


                                   Socket-Programmierung mit IPv6 · Christian Kauhaus · 4
Aktive Socketverbindungen
                                   Date-Client nur mit IPv4


»Old school« Implementierung

class DateClient(object):

   def __init__(self, hostname, port=9000, timeout=15):
       address = socket.gethostbyname(hostname)
       self.socket = socket.socket(socket.AF_INET,
           socket.SOCK_STREAM, 0)
       self.socket.settimeout(timeout)
       self.socket.connect((address, port))

   def query(self):
       self.socket.send('DATErn')
       response = self.socket.recv(1024)
       print 'C: response is %s' % response.strip()




                                  Socket-Programmierung mit IPv6 · Christian Kauhaus · 5
Verhalten des Single-Stack-Clients
                            Ignoriert IPv6-Adressen komplett




Shell-Demo:
 • test.local löst zu IPv4- und IPv6-Adressen auf
 • server6 test.local lauscht auf allen Adressen
 • client4 test.local verbindet sich über IPv4




                                  Socket-Programmierung mit IPv6 · Christian Kauhaus · 6
Programmiertip 1: getaddrinfo()
                   Schnittstelle zwischen Sockets und Außenwelt

getaddrinfo() nutzen. Immer!
                                                                           .
                                                                          GAI
    • Namensauflösung
    • Validierung der Eingabe
    • Filtern nach Socket-Typen
    • address family, socket type, IP protocol


Anti-Pattern
address = socket.gethostbyname(host)



.
                                      Socket-Programmierung mit IPv6 · Christian Kauhaus · 7
Programmiertip 1: getaddrinfo()
                  Schnittstelle zwischen Sockets und Außenwelt

Beispiel:
>>> socket.getaddrinfo('www.python.org', 80, socket.AF_UNSPEC)
[(10, 1, 6, '', ('2001:888:2000:d::a2', 80, 0, 0)),
 (10, 2, 17, '', ('2001:888:2000:d::a2', 80, 0, 0)),
 (10, 3, 0, '', ('2001:888:2000:d::a2', 80, 0, 0)),
 (2, 1, 6, '', ('82.94.164.162', 80)),
 (2, 2, 17, '', ('82.94.164.162', 80)),
 (2, 3, 0, '', ('82.94.164.162', 80))]


  • address family, z. B. 10 = AF_INET6
  • socket type, z. B. 1 = SOCK_STREAM
  • IP protocol, z. B. 6 = SOL_TCP
  • socket address: host, port, flow id, scope


                                     Socket-Programmierung mit IPv6 · Christian Kauhaus · 8
Programmiertip 2: 1:n-Auflösung
                                   Ein Host, mehrere Adressen
Einem Hostnamen sind mehrere Adressen zugeordnet.
                                                                           .
    • IPv4- und IPv6-Adresse                                             1:n
    • mehrere IPv6-Adressen für Multi-Homed Hosts
    • getaddrinfo() gibt eine Liste zurück
    • Reihenfolge nach absteigender Priorität


Anti-Pattern
res = socket.getaddrinfo(...)
sock.connect(res[0][4])



.
                                    Socket-Programmierung mit IPv6 · Christian Kauhaus · 9
Programmiertip 3: Connect-Loop
                                   Alle Adressen durchprobieren
Abbruch nur, wenn keine Adresse erreichbar ist.
                                                                           .
                                                                         Loop
    • Verbindung kommt zustande: fertig
    • Fehler, aber noch Adressen übrig: weitermachen
    • Fehler bei letzter Adresse: letzten Fehler eskalieren


Anti-Pattern
try:
    sock.connect(sockaddr)
except socket.error as e:
    sys.exit(1)



.
                                     Socket-Programmierung mit IPv6 · Christian Kauhaus · 10
Dual-Stack-Code
                              Date-Client mit IPv4 und IPv6




class DateClient(object):

   def __init__(self, hostname, port=9000, timeout=15):
       self.socket = None
       self.connect(hostname, port, timeout)

   def query(self):
       self.socket.send(b'DATErn')
       response = self.socket.recv(1024).decode()
       print('C: response is {}'.format(response.strip()))




                                  Socket-Programmierung mit IPv6 · Christian Kauhaus · 11
Dual-Stack-Code
                      Date-Client mit IPv4 und IPv6 (Fortsetzung)


        def connect(self, host, port, timeout):                  GAI
                                                                .
            exception = None
            for (af, socktype, proto, cname, sockaddr
1:n .           ) in socket.getaddrinfo(host, port, socket.AF_UNSPEC,
                                        socket.SOCK_STREAM, 0):
                try:
                    self.socket = socket.socket(af, socktype, proto)
                    self.socket.settimeout(timeout)
                    self.socket.connect(sockaddr)
                    return
                except socket.error as e:
                    exception = e
            raise exception                .Loop



 .


                                       Socket-Programmierung mit IPv6 · Christian Kauhaus · 12
Verhalten des Dual-Stack-Clients
                                        Verbindung mit IPv6



Shell-Demo:
 • test.local löst zu IPv4- und IPv6-Adressen auf
 • server6 test.local lauscht auf allen Adressen
 • client6 test.local verbindet sich über IPv6
 • server4 test.local lauscht nur auf IPv4-Adresse
 • client6 test.local probiert IPv6 und verbindet sich dann
    über IPv4




                                 Socket-Programmierung mit IPv6 · Christian Kauhaus · 13
Passive Socketverbindungen
                                            Date-Server mit IPv4
class DateServer(object):

   def __init__(self, listen_addresses, port):
       self.listen_addresses = listen_addresses
       self.port = port
       self.threads = list(self.create_threads())

   def create_threads(self):
       for host_or_address in self.listen_addresses:
           address = socket.gethostbyname(host_or_address)
           server = DateSocketServer((address, self.port),
                                     DateHandler)
           yield threading.Thread(target=server.serve_forever)

   def run(self):
       for thread in self.threads:
           thread.start()
       for thread in self.threads:
           thread.join()


                                     Socket-Programmierung mit IPv6 · Christian Kauhaus · 14
Verhalten des Single-Stack-Servers
                                        Verbindung mit IPv4




Shell-Demo:
 • test.local löst zu IPv4- und IPv6-Adressen auf
 • server4 test.local lauscht nur auf IPv4-Adresse
 • client6 test.local verbindet sich über IPv4




                                 Socket-Programmierung mit IPv6 · Christian Kauhaus · 15
Dual-Stack-Code
                              Date-Server mit IPv4 und IPv6

create_threads() muss mehrere Server pro Listen-Item
erzeugen:

class DateServer(object):

   def __init__(self, listen_addresses, port):
       self.listen_addresses = listen_addresses
       self.port = port
       self.threads = list(self.create_threads())

   def create_threads(self):
       servers = []
       for host_or_address in self.listen_addresses:
           servers += self.connect_servers(host_or_address)
       for server in servers:
           yield threading.Thread(target=server.serve_forever)



                                  Socket-Programmierung mit IPv6 · Christian Kauhaus · 16
Dual-Stack-Code
                      Date-Server mit IPv4 und IPv6 (Fortsetzung)

         def connect_servers(self, host_or_address):
             servers = []
             exception = None
                                                                 .GAI
             for (af, socktype, proto, cname, sockaddr
                 ) in socket.getaddrinfo(
       .             host_or_address, self.port, socket.AF_UNSPEC,
    1:n              socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
                 try:
                     servers.append(DateSocketServer(
                          sockaddr[0:2], DateHandler, True, af))
                 except socket.error as e:
                     exception = e
                     continue
                                           .Loop
             if not servers:
                 raise exception
             return servers


.

                                       Socket-Programmierung mit IPv6 · Christian Kauhaus · 17
Dual-Stack-Code
                  Date-Server mit IPv4 und IPv6 (Fortsetzung)


TCPServer erweitern, um address_family im Konstruktor
fallweise zu setzen:

class DateSocketServer(socketserver.ThreadingMixIn,
                       socketserver.TCPServer):
    allow_reuse_address = True

   def __init__(self, server_address, RequestHandlerClass,
                bind_and_activate=True,
                address_family=socket.AF_INET):
       self.address_family = address_family
       super().__init__(server_address, RequestHandlerClass,
                        bind_and_activate)




                                   Socket-Programmierung mit IPv6 · Christian Kauhaus · 18
Verhalten des Dual-Stack-Servers
                              Verbindung mit IPv6 und IPv4




Shell-Demo:
 • test.local löst zu IPv4- und IPv6-Adressen auf
 • server6 test.local lauscht auf allen Adressen
 • client6 test.local verbindet sich über IPv6
 • client4 test.local verbindet sich über IPv4




                                 Socket-Programmierung mit IPv6 · Christian Kauhaus · 19
IP-Adressen
                                             Gar nicht so simpel

IP-Adressen als Strings
entweder:
 • unbehandelt durchreichen
    (z. B. getaddrinfo(), Datenbanken, Logging)
oder:
 • »richtig« parsen und manipulieren (z. B. netaddr, IPy)


Anti-Pattern
re.match(r'[0-9]+.[0-9]+.[0-9]+.[0-9]+', ipaddress)



                                   Socket-Programmierung mit IPv6 · Christian Kauhaus · 20
Zusammenfassung
                         Socket-Programmierung mit IPv6



• Sockets richtig erzeugen
    • getaddrinfo()
    • 1:n Adressauflösung
    • Connect-Loop


• Externe Repräsentation von IP-Adressen mit Respekt
  behandeln

• Dual-Stack Code schreiben!    :-)



                               Socket-Programmierung mit IPv6 · Christian Kauhaus · 21
Vielen Dank!
                                                         Fragen?




      E-Mail kc@gocept.com
      Jabber kc@gocept.com

      Hosting   http://gocept.net/
auf Jobsuche?   http://gocept.com/das-unternehmen/karriere

API definition RFC 3493
 IPv6 porting http://owend.corp.he.net/ipv6/




                               Socket-Programmierung mit IPv6 · Christian Kauhaus · 22

Weitere ähnliche Inhalte

Ähnlich wie Socket Programmierung mit IPv6

Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...
Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...
Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...OPEN KNOWLEDGE GmbH
 
Microservices mit Rust
Microservices mit RustMicroservices mit Rust
Microservices mit RustJens Siebert
 
Kommunikations-APIs von JavaScript (International PHP Conference/WebTechCon 2...
Kommunikations-APIs von JavaScript (International PHP Conference/WebTechCon 2...Kommunikations-APIs von JavaScript (International PHP Conference/WebTechCon 2...
Kommunikations-APIs von JavaScript (International PHP Conference/WebTechCon 2...Christian Wenz
 
Backend-Services mit Rust
Backend-Services mit RustBackend-Services mit Rust
Backend-Services mit RustJens Siebert
 
Daten natuerlich modellieren und verarbeiten mit Neo4j
Daten natuerlich modellieren und verarbeiten mit Neo4jDaten natuerlich modellieren und verarbeiten mit Neo4j
Daten natuerlich modellieren und verarbeiten mit Neo4jPatrick Baumgartner
 
Oracle12c für Entwickler
Oracle12c für EntwicklerOracle12c für Entwickler
Oracle12c für EntwicklerCarsten Czarski
 
Oracle12c für Entwickler
Oracle12c für EntwicklerOracle12c für Entwickler
Oracle12c für Entwickleroraclebudb
 
Javascript auf Client und Server mit node.js - webtech 2010
Javascript auf Client und Server mit node.js - webtech 2010Javascript auf Client und Server mit node.js - webtech 2010
Javascript auf Client und Server mit node.js - webtech 2010Dirk Ginader
 
entwickler.de 05/2023: Go über den Wolken
entwickler.de 05/2023: Go über den Wolkenentwickler.de 05/2023: Go über den Wolken
entwickler.de 05/2023: Go über den WolkenJan Stamer
 
Creasoft - Windows powershell
Creasoft - Windows powershellCreasoft - Windows powershell
Creasoft - Windows powershellCreasoft AG
 
Sockets – Theorie und Implementierung
Sockets – Theorie und ImplementierungSockets – Theorie und Implementierung
Sockets – Theorie und ImplementierungAndreas Roth
 
openstack Übersicht @GPN15
openstack Übersicht @GPN15openstack Übersicht @GPN15
openstack Übersicht @GPN15m1no
 
Caching mit Spring Boot - Pain & Gain @ JCON22
Caching mit Spring Boot - Pain & Gain @ JCON22Caching mit Spring Boot - Pain & Gain @ JCON22
Caching mit Spring Boot - Pain & Gain @ JCON22QAware GmbH
 
W-JAX 2023: Go über den Wolken
W-JAX 2023: Go über den WolkenW-JAX 2023: Go über den Wolken
W-JAX 2023: Go über den WolkenJan Stamer
 
XML-Socket-Server zur Kommunikation mit Flash
XML-Socket-Server zur Kommunikation mit FlashXML-Socket-Server zur Kommunikation mit Flash
XML-Socket-Server zur Kommunikation mit FlashStephan Schmidt
 
Einführung in NoSQL-Datenbanken
Einführung in NoSQL-DatenbankenEinführung in NoSQL-Datenbanken
Einführung in NoSQL-DatenbankenTobias Trelle
 
Apache Cassandra - Einführung
Apache Cassandra - EinführungApache Cassandra - Einführung
Apache Cassandra - EinführungAndreas Finke
 

Ähnlich wie Socket Programmierung mit IPv6 (20)

Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...
Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...
Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...
 
Microservices mit Rust
Microservices mit RustMicroservices mit Rust
Microservices mit Rust
 
Kommunikations-APIs von JavaScript (International PHP Conference/WebTechCon 2...
Kommunikations-APIs von JavaScript (International PHP Conference/WebTechCon 2...Kommunikations-APIs von JavaScript (International PHP Conference/WebTechCon 2...
Kommunikations-APIs von JavaScript (International PHP Conference/WebTechCon 2...
 
Backend-Services mit Rust
Backend-Services mit RustBackend-Services mit Rust
Backend-Services mit Rust
 
Daten natuerlich modellieren und verarbeiten mit Neo4j
Daten natuerlich modellieren und verarbeiten mit Neo4jDaten natuerlich modellieren und verarbeiten mit Neo4j
Daten natuerlich modellieren und verarbeiten mit Neo4j
 
Oracle12c für Entwickler
Oracle12c für EntwicklerOracle12c für Entwickler
Oracle12c für Entwickler
 
Oracle12c für Entwickler
Oracle12c für EntwicklerOracle12c für Entwickler
Oracle12c für Entwickler
 
Javascript auf Client und Server mit node.js - webtech 2010
Javascript auf Client und Server mit node.js - webtech 2010Javascript auf Client und Server mit node.js - webtech 2010
Javascript auf Client und Server mit node.js - webtech 2010
 
entwickler.de 05/2023: Go über den Wolken
entwickler.de 05/2023: Go über den Wolkenentwickler.de 05/2023: Go über den Wolken
entwickler.de 05/2023: Go über den Wolken
 
Node.js
Node.jsNode.js
Node.js
 
Creasoft - Windows powershell
Creasoft - Windows powershellCreasoft - Windows powershell
Creasoft - Windows powershell
 
Sockets – Theorie und Implementierung
Sockets – Theorie und ImplementierungSockets – Theorie und Implementierung
Sockets – Theorie und Implementierung
 
openstack Übersicht @GPN15
openstack Übersicht @GPN15openstack Übersicht @GPN15
openstack Übersicht @GPN15
 
Caching mit Spring Boot - Pain & Gain @ JCON22
Caching mit Spring Boot - Pain & Gain @ JCON22Caching mit Spring Boot - Pain & Gain @ JCON22
Caching mit Spring Boot - Pain & Gain @ JCON22
 
Ein Gopher im Netz
Ein Gopher im NetzEin Gopher im Netz
Ein Gopher im Netz
 
W-JAX 2023: Go über den Wolken
W-JAX 2023: Go über den WolkenW-JAX 2023: Go über den Wolken
W-JAX 2023: Go über den Wolken
 
XML-Socket-Server zur Kommunikation mit Flash
XML-Socket-Server zur Kommunikation mit FlashXML-Socket-Server zur Kommunikation mit Flash
XML-Socket-Server zur Kommunikation mit Flash
 
Web-Services mit Go
Web-Services mit GoWeb-Services mit Go
Web-Services mit Go
 
Einführung in NoSQL-Datenbanken
Einführung in NoSQL-DatenbankenEinführung in NoSQL-Datenbanken
Einführung in NoSQL-Datenbanken
 
Apache Cassandra - Einführung
Apache Cassandra - EinführungApache Cassandra - Einführung
Apache Cassandra - Einführung
 

Socket Programmierung mit IPv6

  • 1. Socket-Programmierung mit IPv6 Christian Kauhaus gocept gmbh & co. kg PyCon DE Leipzig, 7. Oktober 2011 Socket-Programmierung mit IPv6 · Christian Kauhaus · 1
  • 2. Übersicht 1 Einleitung . 2 Aktive Socketverbindungen (Clients) . 3 Passive Socketverbindungen (Server) . 4 IP-Adressen . 5 Zusammenfassung . Socket-Programmierung mit IPv6 · Christian Kauhaus · 2
  • 3. Einleitung Anti-Motivation Brauche ich IPv6-Socketprogrammierung? In der Regel nicht. IPv6-Support umsonst durch: • Bibliotheken (urllib etc.) • Frameworks (Twisted etc.) • vorgelagerter Server (nginx etc.) Aber wenn ich es doch mal brauche..? Socket-Programmierung mit IPv6 · Christian Kauhaus · 3
  • 4. Durchgehendes Beispiel Christians DATE-Protokoll Simples Protokoll, um das aktuelle Datum abzufragen • Client sagt: DATE • Server sagt: DATE YYYY-MM-DD class DateHandler(socketserver.BaseRequestHandler): def handle(self): if self.request.recv(1024).strip() == 'DATE': self.request.send('DATE %srn' % datetime.date.today()) else: self.request.send('ERRORrn') class DateSocketServer(socketserver.ThreadingMixIn, socketserver.TCPServer): allow_reuse_address = True Socket-Programmierung mit IPv6 · Christian Kauhaus · 4
  • 5. Aktive Socketverbindungen Date-Client nur mit IPv4 »Old school« Implementierung class DateClient(object): def __init__(self, hostname, port=9000, timeout=15): address = socket.gethostbyname(hostname) self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) self.socket.settimeout(timeout) self.socket.connect((address, port)) def query(self): self.socket.send('DATErn') response = self.socket.recv(1024) print 'C: response is %s' % response.strip() Socket-Programmierung mit IPv6 · Christian Kauhaus · 5
  • 6. Verhalten des Single-Stack-Clients Ignoriert IPv6-Adressen komplett Shell-Demo: • test.local löst zu IPv4- und IPv6-Adressen auf • server6 test.local lauscht auf allen Adressen • client4 test.local verbindet sich über IPv4 Socket-Programmierung mit IPv6 · Christian Kauhaus · 6
  • 7. Programmiertip 1: getaddrinfo() Schnittstelle zwischen Sockets und Außenwelt getaddrinfo() nutzen. Immer! . GAI • Namensauflösung • Validierung der Eingabe • Filtern nach Socket-Typen • address family, socket type, IP protocol Anti-Pattern address = socket.gethostbyname(host) . Socket-Programmierung mit IPv6 · Christian Kauhaus · 7
  • 8. Programmiertip 1: getaddrinfo() Schnittstelle zwischen Sockets und Außenwelt Beispiel: >>> socket.getaddrinfo('www.python.org', 80, socket.AF_UNSPEC) [(10, 1, 6, '', ('2001:888:2000:d::a2', 80, 0, 0)), (10, 2, 17, '', ('2001:888:2000:d::a2', 80, 0, 0)), (10, 3, 0, '', ('2001:888:2000:d::a2', 80, 0, 0)), (2, 1, 6, '', ('82.94.164.162', 80)), (2, 2, 17, '', ('82.94.164.162', 80)), (2, 3, 0, '', ('82.94.164.162', 80))] • address family, z. B. 10 = AF_INET6 • socket type, z. B. 1 = SOCK_STREAM • IP protocol, z. B. 6 = SOL_TCP • socket address: host, port, flow id, scope Socket-Programmierung mit IPv6 · Christian Kauhaus · 8
  • 9. Programmiertip 2: 1:n-Auflösung Ein Host, mehrere Adressen Einem Hostnamen sind mehrere Adressen zugeordnet. . • IPv4- und IPv6-Adresse 1:n • mehrere IPv6-Adressen für Multi-Homed Hosts • getaddrinfo() gibt eine Liste zurück • Reihenfolge nach absteigender Priorität Anti-Pattern res = socket.getaddrinfo(...) sock.connect(res[0][4]) . Socket-Programmierung mit IPv6 · Christian Kauhaus · 9
  • 10. Programmiertip 3: Connect-Loop Alle Adressen durchprobieren Abbruch nur, wenn keine Adresse erreichbar ist. . Loop • Verbindung kommt zustande: fertig • Fehler, aber noch Adressen übrig: weitermachen • Fehler bei letzter Adresse: letzten Fehler eskalieren Anti-Pattern try: sock.connect(sockaddr) except socket.error as e: sys.exit(1) . Socket-Programmierung mit IPv6 · Christian Kauhaus · 10
  • 11. Dual-Stack-Code Date-Client mit IPv4 und IPv6 class DateClient(object): def __init__(self, hostname, port=9000, timeout=15): self.socket = None self.connect(hostname, port, timeout) def query(self): self.socket.send(b'DATErn') response = self.socket.recv(1024).decode() print('C: response is {}'.format(response.strip())) Socket-Programmierung mit IPv6 · Christian Kauhaus · 11
  • 12. Dual-Stack-Code Date-Client mit IPv4 und IPv6 (Fortsetzung) def connect(self, host, port, timeout): GAI . exception = None for (af, socktype, proto, cname, sockaddr 1:n . ) in socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM, 0): try: self.socket = socket.socket(af, socktype, proto) self.socket.settimeout(timeout) self.socket.connect(sockaddr) return except socket.error as e: exception = e raise exception .Loop . Socket-Programmierung mit IPv6 · Christian Kauhaus · 12
  • 13. Verhalten des Dual-Stack-Clients Verbindung mit IPv6 Shell-Demo: • test.local löst zu IPv4- und IPv6-Adressen auf • server6 test.local lauscht auf allen Adressen • client6 test.local verbindet sich über IPv6 • server4 test.local lauscht nur auf IPv4-Adresse • client6 test.local probiert IPv6 und verbindet sich dann über IPv4 Socket-Programmierung mit IPv6 · Christian Kauhaus · 13
  • 14. Passive Socketverbindungen Date-Server mit IPv4 class DateServer(object): def __init__(self, listen_addresses, port): self.listen_addresses = listen_addresses self.port = port self.threads = list(self.create_threads()) def create_threads(self): for host_or_address in self.listen_addresses: address = socket.gethostbyname(host_or_address) server = DateSocketServer((address, self.port), DateHandler) yield threading.Thread(target=server.serve_forever) def run(self): for thread in self.threads: thread.start() for thread in self.threads: thread.join() Socket-Programmierung mit IPv6 · Christian Kauhaus · 14
  • 15. Verhalten des Single-Stack-Servers Verbindung mit IPv4 Shell-Demo: • test.local löst zu IPv4- und IPv6-Adressen auf • server4 test.local lauscht nur auf IPv4-Adresse • client6 test.local verbindet sich über IPv4 Socket-Programmierung mit IPv6 · Christian Kauhaus · 15
  • 16. Dual-Stack-Code Date-Server mit IPv4 und IPv6 create_threads() muss mehrere Server pro Listen-Item erzeugen: class DateServer(object): def __init__(self, listen_addresses, port): self.listen_addresses = listen_addresses self.port = port self.threads = list(self.create_threads()) def create_threads(self): servers = [] for host_or_address in self.listen_addresses: servers += self.connect_servers(host_or_address) for server in servers: yield threading.Thread(target=server.serve_forever) Socket-Programmierung mit IPv6 · Christian Kauhaus · 16
  • 17. Dual-Stack-Code Date-Server mit IPv4 und IPv6 (Fortsetzung) def connect_servers(self, host_or_address): servers = [] exception = None .GAI for (af, socktype, proto, cname, sockaddr ) in socket.getaddrinfo( . host_or_address, self.port, socket.AF_UNSPEC, 1:n socket.SOCK_STREAM, 0, socket.AI_PASSIVE): try: servers.append(DateSocketServer( sockaddr[0:2], DateHandler, True, af)) except socket.error as e: exception = e continue .Loop if not servers: raise exception return servers . Socket-Programmierung mit IPv6 · Christian Kauhaus · 17
  • 18. Dual-Stack-Code Date-Server mit IPv4 und IPv6 (Fortsetzung) TCPServer erweitern, um address_family im Konstruktor fallweise zu setzen: class DateSocketServer(socketserver.ThreadingMixIn, socketserver.TCPServer): allow_reuse_address = True def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True, address_family=socket.AF_INET): self.address_family = address_family super().__init__(server_address, RequestHandlerClass, bind_and_activate) Socket-Programmierung mit IPv6 · Christian Kauhaus · 18
  • 19. Verhalten des Dual-Stack-Servers Verbindung mit IPv6 und IPv4 Shell-Demo: • test.local löst zu IPv4- und IPv6-Adressen auf • server6 test.local lauscht auf allen Adressen • client6 test.local verbindet sich über IPv6 • client4 test.local verbindet sich über IPv4 Socket-Programmierung mit IPv6 · Christian Kauhaus · 19
  • 20. IP-Adressen Gar nicht so simpel IP-Adressen als Strings entweder: • unbehandelt durchreichen (z. B. getaddrinfo(), Datenbanken, Logging) oder: • »richtig« parsen und manipulieren (z. B. netaddr, IPy) Anti-Pattern re.match(r'[0-9]+.[0-9]+.[0-9]+.[0-9]+', ipaddress) Socket-Programmierung mit IPv6 · Christian Kauhaus · 20
  • 21. Zusammenfassung Socket-Programmierung mit IPv6 • Sockets richtig erzeugen • getaddrinfo() • 1:n Adressauflösung • Connect-Loop • Externe Repräsentation von IP-Adressen mit Respekt behandeln • Dual-Stack Code schreiben! :-) Socket-Programmierung mit IPv6 · Christian Kauhaus · 21
  • 22. Vielen Dank! Fragen? E-Mail kc@gocept.com Jabber kc@gocept.com Hosting http://gocept.net/ auf Jobsuche? http://gocept.com/das-unternehmen/karriere API definition RFC 3493 IPv6 porting http://owend.corp.he.net/ipv6/ Socket-Programmierung mit IPv6 · Christian Kauhaus · 22