Hello, I'm looking at making the changes to support IPv6 multicast groups as described in ticket 6597 but wanted to get some feedback (and get a feel whether this is even desirable) before formally submitting any patches.
Specifically: 1. I've read [1] and it alludes to udp hopefully disappearing, is that something in the works? Is there a new approach to solving this problem I should look at? A branch in the works where this (conceptual) change belongs? Note: The addressFamily attribute referenced already exists and is set properly for IPv6. 2. The attached change has the side effect that calls to ReactorBase.resolve() with IPv6 literals will now likely succeed where they may have failed in the past. That means clients counting on resolve raising an exception for an IPv6 literal will break. Not sure whether this is considered a compatibility issue, but I wanted to raise it. 3. One alternative to the above would be a complete API separation, via something like joinIPv6Group(), and a new resolve. Is that more appealing in this case? Caveats: 1. I have not finished all of the documentation related to developers, I will do so prior to formal submission. 2. I know I need tests and docs and will submit them with the final changes. On to the patches. With these changes, I can use the joinGroup API to add myself to an IPv6 multicast group on Linux (verified via /proc/net/igmp6). Additionally, trial reports the same two failures before and after these changes (twisted.python.test.test_release.APIBuilderTests.test_build and test_buildWithPolicy). These changes struck me as the obvious approach, but given the changes to resolve, not necessarily the best. diff --git a/twisted/internet/base.py b/twisted/internet/base.py index 4f2c862..e813741 100644 --- a/twisted/internet/base.py +++ b/twisted/internet/base.py @@ -567,6 +567,8 @@ class ReactorBase(object): return defer.succeed('0.0.0.0') if abstract.isIPAddress(name): return defer.succeed(name) + elif abstract.isIPv6Address(name): + return defer.succeed(name) return self.resolver.getHostByName(name, timeout) # Installation. diff --git a/twisted/internet/udp.py b/twisted/internet/udp.py index b5a5322..210b079 100644 --- a/twisted/internet/udp.py +++ b/twisted/internet/udp.py @@ -485,7 +485,10 @@ class MulticastMixin: def _joinAddr1(self, addr, interface, join): - return self.reactor.resolve(interface).addCallback(self._joinAddr2, addr, join) + if self.addressFamily == socket.AF_INET: + return self.reactor.resolve(interface).addCallback(self._joinAddr2, addr, join) + else: + return self.reactor.resolve(interface).addCallback(self._joinAddrIPv6, addr, join) def _joinAddr2(self, interface, addr, join): @@ -500,6 +503,18 @@ class MulticastMixin: except socket.error as e: return failure.Failure(error.MulticastJoinError(addr, interface, *e.args)) + def _joinAddrIPv6(self, interface, addr, join): + addr = socket.inet_pton(socket.AF_INET6, addr) + interface = socket.inet_pton(socket.AF_INET6, interface) + if join: + cmd = socket.IPV6_JOIN_GROUP + else: + cmd = socket.IPV6_LEAVE_GROUP + try: + self.socket.setsockopt(socket.IPPROTO_IPV6, cmd, addr + interface) + except socket.error as e: + return failure.Failure(error.MulticastJoinError(addr, interface, *e.args)) + def leaveGroup(self, addr, interface=""): """Leave multicast group, return Deferred of success.""" This does require the client specify the interface argument when calling joinGroup, e.g. self.transport.joinGroup("ff02::1", interface="::"). Thanks in advance for any feedback! -Jason Litzinger [1] http://twistedmatrix.com/pipermail/twisted-python/2016-March/030188.html _______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python