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)

Reply via email to