net: support all PacketConn and Conn returned by Resolver.Dial

Allow the Resolver.Dial func to return instances of Conn other than
*TCPConn and *UDPConn. If the Conn is also a PacketConn, assume DNS
messages transmitted over the Conn adhere to section 4.2.1. "UDP usage".
Otherwise, follow section 4.2.2. "TCP usage".

Provides a hook mechanism so that DNS queries generated by the net
package may be answered or modified before being sent to over the
network.

Updates #19910

Change-Id: Ib089a28ad4a1848bbeaf624ae889f1e82d56655b
Reviewed-on: https://go-review.googlesource.com/45153
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Ben Burkert 2017-06-08 13:19:28 -07:00 committed by Brad Fitzpatrick
parent d55d7b9397
commit d8a7990ffa
4 changed files with 86 additions and 34 deletions

View file

@ -36,14 +36,14 @@ type dnsConn interface {
dnsRoundTrip(query *dnsMsg) (*dnsMsg, error)
}
func (c *UDPConn) dnsRoundTrip(query *dnsMsg) (*dnsMsg, error) {
return dnsRoundTripUDP(c, query)
// dnsPacketConn implements the dnsConn interface for RFC 1035's
// "UDP usage" transport mechanism. Conn is a packet-oriented connection,
// such as a *UDPConn.
type dnsPacketConn struct {
Conn
}
// dnsRoundTripUDP implements the dnsRoundTrip interface for RFC 1035's
// "UDP usage" transport mechanism. c should be a packet-oriented connection,
// such as a *UDPConn.
func dnsRoundTripUDP(c io.ReadWriter, query *dnsMsg) (*dnsMsg, error) {
func (c *dnsPacketConn) dnsRoundTrip(query *dnsMsg) (*dnsMsg, error) {
b, ok := query.Pack()
if !ok {
return nil, errors.New("cannot marshal DNS message")
@ -69,14 +69,14 @@ func dnsRoundTripUDP(c io.ReadWriter, query *dnsMsg) (*dnsMsg, error) {
}
}
func (c *TCPConn) dnsRoundTrip(out *dnsMsg) (*dnsMsg, error) {
return dnsRoundTripTCP(c, out)
// dnsStreamConn implements the dnsConn interface for RFC 1035's
// "TCP usage" transport mechanism. Conn is a stream-oriented connection,
// such as a *TCPConn.
type dnsStreamConn struct {
Conn
}
// dnsRoundTripTCP implements the dnsRoundTrip interface for RFC 1035's
// "TCP usage" transport mechanism. c should be a stream-oriented connection,
// such as a *TCPConn.
func dnsRoundTripTCP(c io.ReadWriter, query *dnsMsg) (*dnsMsg, error) {
func (c *dnsStreamConn) dnsRoundTrip(query *dnsMsg) (*dnsMsg, error) {
b, ok := query.Pack()
if !ok {
return nil, errors.New("cannot marshal DNS message")