Socket-Programmierung mit IPv6           Christian Kauhaus            gocept gmbh & co. kg   PyCon DE Leipzig, 7. Oktober ...
Übersicht1 Einleitung.2 Aktive Socketverbindungen (Clients).3 Passive Socketverbindungen (Server).4 IP-Adressen.5 Zusammen...
Einleitung                                              Anti-MotivationBrauche ich IPv6-Socketprogrammierung?In der Regel ...
Durchgehendes Beispiel                                  Christians DATE-ProtokollSimples Protokoll, um das aktuelle Datum ...
Aktive Socketverbindungen                                   Date-Client nur mit IPv4»Old school« Implementierungclass Date...
Verhalten des Single-Stack-Clients                            Ignoriert IPv6-Adressen komplettShell-Demo: • test.local lös...
Programmiertip 1: getaddrinfo()                   Schnittstelle zwischen Sockets und Außenweltgetaddrinfo() nutzen. Immer!...
Programmiertip 1: getaddrinfo()                  Schnittstelle zwischen Sockets und AußenweltBeispiel:>>> socket.getaddrin...
Programmiertip 2: 1:n-Auflösung                                   Ein Host, mehrere AdressenEinem Hostnamen sind mehrere Ad...
Programmiertip 3: Connect-Loop                                   Alle Adressen durchprobierenAbbruch nur, wenn keine Adres...
Dual-Stack-Code                              Date-Client mit IPv4 und IPv6class DateClient(object):   def __init__(self, h...
Dual-Stack-Code                      Date-Client mit IPv4 und IPv6 (Fortsetzung)        def connect(self, host, port, time...
Verhalten des Dual-Stack-Clients                                        Verbindung mit IPv6Shell-Demo: • test.local löst z...
Passive Socketverbindungen                                            Date-Server mit IPv4class DateServer(object):   def ...
Verhalten des Single-Stack-Servers                                        Verbindung mit IPv4Shell-Demo: • test.local löst...
Dual-Stack-Code                              Date-Server mit IPv4 und IPv6create_threads() muss mehrere Server pro Listen-...
Dual-Stack-Code                      Date-Server mit IPv4 und IPv6 (Fortsetzung)         def connect_servers(self, host_or...
Dual-Stack-Code                  Date-Server mit IPv4 und IPv6 (Fortsetzung)TCPServer erweitern, um address_family im Kons...
Verhalten des Dual-Stack-Servers                              Verbindung mit IPv6 und IPv4Shell-Demo: • test.local löst zu...
IP-Adressen                                             Gar nicht so simpelIP-Adressen als Stringsentweder: • unbehandelt ...
Zusammenfassung                         Socket-Programmierung mit IPv6• Sockets richtig erzeugen    • getaddrinfo()    • 1...
Vielen Dank!                                                         Fragen?      E-Mail kc@gocept.com      Jabber kc@goce...
Upcoming SlideShare
Loading in …5
×

Socket Programmierung mit IPv6

2,315 views

Published on

Vortrag zur Socket-Programmierung von Dual-Stack-Anwendungen in Python von der PyCon DE 2011 Leipzig.

http://de.pycon.org/2011/schedule/sessions/42/

http://blip.tv/episode/5632211

4 Comments
2 Likes
Statistics
Notes
No Downloads
Views
Total views
2,315
On SlideShare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
44
Comments
4
Likes
2
Embeds 0
No embeds

No notes for slide

Socket Programmierung mit IPv6

  1. 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. 2. Übersicht1 Einleitung.2 Aktive Socketverbindungen (Clients).3 Passive Socketverbindungen (Server).4 IP-Adressen.5 Zusammenfassung. Socket-Programmierung mit IPv6 · Christian Kauhaus · 2
  3. 3. Einleitung Anti-MotivationBrauche 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. 4. Durchgehendes Beispiel Christians DATE-ProtokollSimples Protokoll, um das aktuelle Datum abzufragen • Client sagt: DATE • Server sagt: DATE YYYY-MM-DDclass 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. 5. Aktive Socketverbindungen Date-Client nur mit IPv4»Old school« Implementierungclass 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. 6. Verhalten des Single-Stack-Clients Ignoriert IPv6-Adressen komplettShell-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. 7. Programmiertip 1: getaddrinfo() Schnittstelle zwischen Sockets und Außenweltgetaddrinfo() nutzen. Immer! . GAI • Namensauflösung • Validierung der Eingabe • Filtern nach Socket-Typen • address family, socket type, IP protocolAnti-Patternaddress = socket.gethostbyname(host). Socket-Programmierung mit IPv6 · Christian Kauhaus · 7
  8. 8. Programmiertip 1: getaddrinfo() Schnittstelle zwischen Sockets und AußenweltBeispiel:>>> 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. 9. Programmiertip 2: 1:n-Auflösung Ein Host, mehrere AdressenEinem 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ätAnti-Patternres = socket.getaddrinfo(...)sock.connect(res[0][4]). Socket-Programmierung mit IPv6 · Christian Kauhaus · 9
  10. 10. Programmiertip 3: Connect-Loop Alle Adressen durchprobierenAbbruch nur, wenn keine Adresse erreichbar ist. . Loop • Verbindung kommt zustande: fertig • Fehler, aber noch Adressen übrig: weitermachen • Fehler bei letzter Adresse: letzten Fehler eskalierenAnti-Patterntry: sock.connect(sockaddr)except socket.error as e: sys.exit(1). Socket-Programmierung mit IPv6 · Christian Kauhaus · 10
  11. 11. Dual-Stack-Code Date-Client mit IPv4 und IPv6class DateClient(object): def __init__(self, hostname, port=9000, timeout=15): self.socket = None self.connect(hostname, port, timeout) def query(self): self.socket.send(bDATErn) response = self.socket.recv(1024).decode() print(C: response is {}.format(response.strip())) Socket-Programmierung mit IPv6 · Christian Kauhaus · 11
  12. 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, sockaddr1: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. 13. Verhalten des Dual-Stack-Clients Verbindung mit IPv6Shell-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. 14. Passive Socketverbindungen Date-Server mit IPv4class 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. 15. Verhalten des Single-Stack-Servers Verbindung mit IPv4Shell-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. 16. Dual-Stack-Code Date-Server mit IPv4 und IPv6create_threads() muss mehrere Server pro Listen-Itemerzeugen: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. 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. 18. Dual-Stack-Code Date-Server mit IPv4 und IPv6 (Fortsetzung)TCPServer erweitern, um address_family im Konstruktorfallweise 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. 19. Verhalten des Dual-Stack-Servers Verbindung mit IPv6 und IPv4Shell-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. 20. IP-Adressen Gar nicht so simpelIP-Adressen als Stringsentweder: • unbehandelt durchreichen (z. B. getaddrinfo(), Datenbanken, Logging)oder: • »richtig« parsen und manipulieren (z. B. netaddr, IPy)Anti-Patternre.match(r[0-9]+.[0-9]+.[0-9]+.[0-9]+, ipaddress) Socket-Programmierung mit IPv6 · Christian Kauhaus · 20
  21. 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. 22. Vielen Dank! Fragen? E-Mail kc@gocept.com Jabber kc@gocept.com Hosting http://gocept.net/auf Jobsuche? http://gocept.com/das-unternehmen/karriereAPI definition RFC 3493 IPv6 porting http://owend.corp.he.net/ipv6/ Socket-Programmierung mit IPv6 · Christian Kauhaus · 22

×