I did a mod to enable registry on ipv6. It only support udp at this moment.
How do you guys think of full ipv6 support?
For my case, plug in a few devices with zero configuration and rpyc just
works.
diff -urN rpyc-3.2.2/rpyc/core/stream.py rpyc-3.2.2.new/rpyc/core/stream.py
--- rpyc-3.2.2/rpyc/core/stream.py 2012-06-01 05:27:09.000000000 +0930
+++ rpyc-3.2.2.new/rpyc/core/stream.py 2012-06-19 15:42:16.258596564 +0930
@@ -87,9 +87,11 @@
@classmethod
def _connect(cls, host, port, family = socket.AF_INET, socktype = socket.SOCK_STREAM,
proto = 0, timeout = 3, nodelay = False):
+ family, socktype, proto, canonname, sockaddr = \
+ socket.getaddrinfo(host, port, family, socktype, proto)[0]
s = socket.socket(family, socktype, proto)
s.settimeout(timeout)
- s.connect((host, port))
+ s.connect(sockaddr)
if nodelay:
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
return s
diff -urN rpyc-3.2.2/rpyc/scripts/rpyc_registry.py rpyc-3.2.2.new/rpyc/scripts/rpyc_registry.py
--- rpyc-3.2.2/rpyc/scripts/rpyc_registry.py 2012-06-01 05:27:09.000000000 +0930
+++ rpyc-3.2.2.new/rpyc/scripts/rpyc_registry.py 2012-06-19 15:42:16.258596564 +0930
@@ -22,6 +22,8 @@
default=False, help="quiet mode (only errors are logged)")
parser.add_option("-t", "--timeout", action="store", dest="pruning_timeout",
type="int", default=DEFAULT_PRUNING_TIMEOUT, help="sets a custom pruning timeout")
+parser.add_option("-6", "--ipv6", action="store_true", dest="ipv6",
+ default=False, help="use ipv6 instead of ipv4")
def main():
options, args = parser.parse_args()
@@ -32,7 +34,8 @@
raise ValueError("invalid TCP/UDP port %r" % (options.port,))
if options.mode.lower() == "udp":
- server = UDPRegistryServer(port = options.port,
+ host = '::' if options.ipv6 else '0.0.0.0'
+ server = UDPRegistryServer(host = host, port = options.port,
pruning_timeout = options.pruning_timeout)
elif options.mode.lower() == "tcp":
server = TCPRegistryServer(port = options.port,
diff -urN rpyc-3.2.2/rpyc/utils/registry.py rpyc-3.2.2.new/rpyc/utils/registry.py
--- rpyc-3.2.2/rpyc/utils/registry.py 2012-04-25 18:48:10.000000000 +0930
+++ rpyc-3.2.2.new/rpyc/utils/registry.py 2012-06-19 16:15:00.678291184 +0930
@@ -147,7 +147,7 @@
raise ValueError("server is already running")
if self.sock is None:
raise ValueError("object disposed")
- self.logger.debug("server started on %s:%s", *self.sock.getsockname())
+ self.logger.debug("server started on %s:%s", *self.sock.getsockname()[:2])
try:
try:
self.active = True
@@ -174,8 +174,10 @@
def __init__(self, host = "0.0.0.0", port = REGISTRY_PORT,
pruning_timeout = None, logger = None):
- sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- sock.bind((host, port))
+ family, socktype, proto, canonname, sockaddr = \
+ socket.getaddrinfo(host, port, 0, socket.SOCK_DGRAM)[0]
+ sock = socket.socket(family, socktype, proto)
+ sock.bind(sockaddr)
sock.settimeout(0.5)
RegistryServer.__init__(self, sock, pruning_timeout = pruning_timeout,
logger = logger)
@@ -200,7 +202,8 @@
def __init__(self, host = "0.0.0.0", port = REGISTRY_PORT,
pruning_timeout = None, logger = None, reuse_addr = True):
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ family = socket.AF_INET6 if ipv6 else socket.AF_INET
+ sock = socket.socket(family, socket.SOCK_STREAM)
if reuse_addr and sys.platform != "win32":
# warning: reuseaddr is not what you expect on windows!
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
@@ -291,18 +294,23 @@
"""
def __init__(self, ip = "255.255.255.255", port = REGISTRY_PORT, timeout = 2,
- bcast = None, logger = None):
+ ipv6=False, bcast = None, logger = None):
RegistryClient.__init__(self, ip = ip, port = port, timeout = timeout,
logger = logger)
- if bcast is None:
- bcast = "255" in ip.split(".")
- self.bcast = bcast
+ if ipv6:
+ self.sock_family = socket.AF_INET6
+ self.bcast = False
+ else:
+ self.sock_family = socket.AF_INET
+ if bcast is None:
+ bcast = "255" in ip.split(".")
+ self.bcast = bcast
def _get_logger(self):
return logging.getLogger('REGCLNT/UDP')
def discover(self, name):
- sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ sock = socket.socket(self.sock_family, socket.SOCK_DGRAM)
try:
if self.bcast:
@@ -323,7 +331,7 @@
def register(self, aliases, port):
self.logger.info("registering on %s:%s", self.ip, self.port)
- sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ sock = socket.socket(self.sock_family, socket.SOCK_DGRAM)
try:
if self.bcast:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True)
@@ -334,7 +342,8 @@
while time.time() < tmax:
sock.settimeout(tmax - time.time())
try:
- data, (rip, rport) = sock.recvfrom(MAX_DGRAM_SIZE)
+ data, address = sock.recvfrom(MAX_DGRAM_SIZE)
+ rip, rport = address[:2]
except socket.timeout:
self.logger.warn("no registry acknowledged")
break
@@ -354,7 +363,7 @@
def unregister(self, port):
self.logger.info("unregistering from %s:%s", self.ip, self.port)
- sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ sock = socket.socket(self.sock_family, socket.SOCK_DGRAM)
try:
if self.bcast:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True)