Package: python-twisted-names Version: 14.0.2-2 Severity: grave Tags: patch Justification: renders package unusable
Dear Maintainers, Upstream bug: http://twistedmatrix.com/trac/ticket/6949 When using twisted.names.client to request a large number of DNS-SD records, whose answer exceeds the UDP limit (512B), the message has to be remade using TCP. This makes twisted.names useless for this use and many others cases as soon as the response is too large. I already proposed a patch June 13th, 2014 (4 months ago), without reaction since now. === PATCH STARTS HERE Description: twisted.names.server never truncates datagram responses #6949 Upstream bug: http://twistedmatrix.com/trac/ticket/6949 . Until it supports wiki:EDNS0, twisted.names.server ought to limit the size of its response messages to 512B. . But because of the way dns.Message.decode sets the maxSize=0 and because of the way server re-uses the request message for its responses, it never actually truncates large messages. . This probably means that some responses will be dropped or fragmented on their route across the Internet, which means that clients have to wait for a timeout before re-issuing the query over TCP. . twisted (14.0.2-2) unstable; urgency=medium . Author: Philippe Goetz <philippe.go...@siemens.com> --- Origin: other, <url of original patch> Bug: http://twistedmatrix.com/trac/ticket/6949 Bug-Debian: http://bugs.debian.org/<bugnumber> Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> Forwarded: <no|not-needed|url proving that it has been forwarded> Reviewed-By: <name and email of someone who approved the patch> Last-Update: <YYYY-MM-DD> --- twisted-14.0.2.orig/twisted/names/dns.py +++ twisted-14.0.2/twisted/names/dns.py @@ -2738,6 +2738,9 @@ class DNSDatagramProtocol(DNSMixin, prot m = Message() try: m.fromStr(data) + m.maxSize = min(512, self.transport.maxPacketSize) + if m.trunc: + m.trunc = addr # will be used for TCP except EOFError: log.msg("Truncated packet (%d bytes) from %s" % (len(data), addr)) return --- twisted-14.0.2.orig/twisted/names/client.py +++ twisted-14.0.2/twisted/names/client.py @@ -369,7 +369,24 @@ class Resolver(common.ResolverBase): the answers section, the authority section, and the additional section. """ if message.trunc: - return self.queryTCP(message.queries).addCallback(self.filterAnswers) + timeout = 10 + if isinstance(message.trunc, tuple): + # Truncated message got from UDP server as trunc is an address and not a bool + # NOTE: UDP server should be also a TCP server (on the address and port) as required by RFCs + addr = message.trunc + # Try to reuse a connection already established with the server + for connection in self.connections: + if connection.transport.addr == addr: + return connection.query(message.queries, timeout).addCallback(self.filterAnswers) + # Build a new connection with the server + deferred = defer.Deferred() + self._reactor.connectTCP(addr[0], addr[1], self.factory) + self.pending.append((deferred, message.queries, timeout)) + return deferred.addCallback(self.filterAnswers) + # Don't use this call as it will establish the connection with another server, + # which is more than likely not able to process the request. + # TODO If here, it is probably a truncated message got from TCP! + return self.queryTCP(message.queries, timeout).addCallback(self.filterAnswers) if message.rCode != dns.OK: return failure.Failure(self.exceptionForCode(message.rCode)(message)) return (message.answers, message.authority, message.additional) --- twisted-14.0.2.orig/twisted/names/test/test_rootresolve.py +++ twisted-14.0.2/twisted/names/test/test_rootresolve.py @@ -119,6 +119,10 @@ class MemoryDatagramTransport(object): """ pass + @property + def maxPacketSize(self): + return self._maxPacketSize + verifyClass(IUDPTransport, MemoryDatagramTransport) --- twisted-14.0.2.orig/twisted/names/test/test_client.py +++ twisted-14.0.2/twisted/names/test/test_client.py @@ -1059,7 +1059,7 @@ class FilterAnswersTests(unittest.TestCa m = dns.Message(trunc=True) m.addQuery(b'example.com') - def queryTCP(queries): + def queryTCP(queries, timeout = 10): self.assertEqual(queries, m.queries) response = dns.Message() response.answers = ['answer'] --- twisted-14.0.2.orig/twisted/test/proto_helpers.py +++ twisted-14.0.2/twisted/test/proto_helpers.py @@ -100,10 +100,14 @@ class FakeDatagramTransport: def __init__(self): self.written = [] + self._maxPacketSize = 512 def write(self, packet, addr=noAddr): self.written.append((packet, addr)) + @property + def maxPacketSize(self): + return self._maxPacketSize @implementer(ITransport, IConsumer, IPushProducer) === PATCH ENDS HERE -- System Information: Debian Release: jessie/sid APT prefers testing-updates APT policy: (500, 'testing-updates'), (500, 'testing') Architecture: amd64 (x86_64) Kernel: Linux 3.14-1-amd64 (SMP w/1 CPU core) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages python-twisted-names depends on: ii python 2.7.8-1 ii python-twisted-core 14.0.2-2 python-twisted-names recommends no packages. python-twisted-names suggests no packages. -- no debconf information -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org