Opened 9 years ago

Closed 8 years ago

#3217 defect closed fixed (fixed)

twisted.names.dns: DNSDatagramProtocol doesn't release unused UDP-ports

Reported by: pittipatti Owned by:
Priority: normal Milestone:
Component: names Keywords: names
Cc: Branch:


In class "DNSDatagramProtocol" the function "startListening" attaches a UDP-port to the reactor, but leaves it attached even when the protocol is closed.

In my application I have to create new resolvers for querying many different nameservers.

Please have a look at the attachments with sample code which results

  1. in many listening UDP-ports ( please see in another console: netstat -anpu | grep python )
  2. in a (rather strange) exception (ImportError: cannot import name SHA)

As mentioned above, DNSDatagramProtocol.startListening() executes reactor.listenUDP, but the returned port isn't saved anywere, so it can't be closed. I saved it as a instance-variable but have no clue where to call the stopListening()-function, since DNSDatagramProtocol.stopProtocol() or DNSDatagramProtocol.doStop() don't seem to be called at all.

Attachments (2)

example1 (358 bytes) - added by pittipatti 9 years ago.
Example 1
example2 (360 bytes) - added by pittipatti 9 years ago.
Example 2

Download all attachments as: .zip

Change History (6)

Changed 9 years ago by pittipatti

Attachment: example1 added

Example 1

Changed 9 years ago by pittipatti

Attachment: example2 added

Example 2

comment:1 Changed 9 years ago by Jean-Paul Calderone

doStop (and stopProtocol) are called when the DatagramProtocol is no longer associated with any port. So they're not appropriate hooks for disassociating a DatagramProtocol with its port. ;)

The result of reactor.listenUDP is saved, although in a somewhat roundabout manner (it's necessary in order to send the DNS traffic, after all). Once the port is set up, it is passed to DatagramProtocol.makeConnection which is implemented to save it at the transport attribute. So you do have a reference to it, via the transport attribute of the DNSDatagramProtocol. However, your application code still has no reference to it, since you have a Resolver (or worse, a ResolverChain), not a DNSDatagramProtocol.

I don't think the protocol can know when to clean itself up. Perhaps Resolver should have an API for cleanup, though, so that applications, which do know when to clean things up, can perform the necessary cleanup.

However, it may be that what you really want is for the server to which the query is sent to be more easily controlled. You don't have to have a different UDP port for each server you're querying, it's just that the Resolver API currently makes it difficult or impossible to specify the server to use for each query. If this were possible, you could have a single UDP port and issue all of your queries over it.

comment:2 Changed 8 years ago by jknight

Probably superseded by #3342.

comment:3 Changed 8 years ago by Jean-Paul Calderone

Resolution: fixed
Status: newclosed

Fixed in r24401

comment:4 Changed 6 years ago by <automation>

Owner: Jean-Paul Calderone deleted
Note: See TracTickets for help on using tickets.