The current (v2) version of the module requires the packet connection to be a *net.UDPConn, while the TCP part is abstracted behind net.Listener. That is done so that dns.SessionUDP could be used, but it has a limited interface. An example of a thing that could be done with a custom net.PacketConn is getting the original destination address along with the source (remote) address, which is useful when listening on 0.0.0.0.