Home > front end >  How to create a dual-stack (v4 v6) python UDP server?
How to create a dual-stack (v4 v6) python UDP server?

Time:05-05

By searching for 'python dual-stack', I found https://bugs.python.org/issue25667 where someone mentions that this was already resolved in https://bugs.python.org/issue17561. In the latter issue, one of the last messages helpfully mentions what the implemented solution is:

# IPv4 only
>>> socket.create_server(addr)  
# IPv6 only
>>> socket.create_server(addr, family=socket.AF_INET6)
# IPv4   IPv6
>>> socket.create_server(addr, family=socket.AF_INET6, dualstack_ipv6=True)

However, I was looking for a generic solution. Or rather, I was looking for UDP but figured that, because this is on the IP layer, any solution would be generic. It turns out that create_server() is TCP-only.

Binding to both v4 and v6 manually means I cannot just call recvfrom() and let it block until a packet comes in, because then a v6 packet might be queued while it's blocking on the v4 recvfrom call or vice versa. So I guess I need to use threading?

What is the best way to make a dual-stack UDP server in python 3.x? For me, a Linux solution would be sufficient, but of course platform-independent answers are even better.

Basically, how to write this in dual-stack:

import socket

server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(('0.0.0.0', 53))

while True:
    message, address = server_socket.recvfrom(1400)

CodePudding user response:

At least under Linux, creating an IPv6 socket listens for both IPv6 and IPv4 connections. That is, given this code:

import socket
s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
s.bind(('::', 9090))
while True:
   message, address = s.recvfrom(1024)
   print(address, "says: ", message.decode())

I can connect using IPv4:

echo hello world | nc -u 127.0.0.1 9090

Which results in:

('::ffff:127.0.0.1', 36694, 0, 0) says:  hello world

Or I can connect using IPv6:

echo hello world | nc -u ::1 9090

Which results in:

('::1', 51880, 0, 0) says:  hello world
  • Related