summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/miekg/dns/udp.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/miekg/dns/udp.go')
-rw-r--r--vendor/github.com/miekg/dns/udp.go52
1 files changed, 48 insertions, 4 deletions
diff --git a/vendor/github.com/miekg/dns/udp.go b/vendor/github.com/miekg/dns/udp.go
index 12a209678..f3f31a7ac 100644
--- a/vendor/github.com/miekg/dns/udp.go
+++ b/vendor/github.com/miekg/dns/udp.go
@@ -4,6 +4,9 @@ package dns
import (
"net"
+
+ "golang.org/x/net/ipv4"
+ "golang.org/x/net/ipv6"
)
// SessionUDP holds the remote address and the associated
@@ -34,12 +37,53 @@ func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, e
return n, err
}
+func setUDPSocketOptions(conn *net.UDPConn) error {
+ // Try setting the flags for both families and ignore the errors unless they
+ // both error.
+ err6 := ipv6.NewPacketConn(conn).SetControlMessage(ipv6.FlagDst|ipv6.FlagInterface, true)
+ err4 := ipv4.NewPacketConn(conn).SetControlMessage(ipv4.FlagDst|ipv4.FlagInterface, true)
+ if err6 != nil && err4 != nil {
+ return err4
+ }
+ return nil
+}
+
+// parseDstFromOOB takes oob data and returns the destination IP.
+func parseDstFromOOB(oob []byte) net.IP {
+ // Start with IPv6 and then fallback to IPv4
+ // TODO(fastest963): Figure out a way to prefer one or the other. Looking at
+ // the lvl of the header for a 0 or 41 isn't cross-platform.
+ var dst net.IP
+ cm6 := new(ipv6.ControlMessage)
+ if cm6.Parse(oob) == nil {
+ dst = cm6.Dst
+ }
+ if dst == nil {
+ cm4 := new(ipv4.ControlMessage)
+ if cm4.Parse(oob) == nil {
+ dst = cm4.Dst
+ }
+ }
+ return dst
+}
+
// correctSource takes oob data and returns new oob data with the Src equal to the Dst
func correctSource(oob []byte) []byte {
- dst, err := parseUDPSocketDst(oob)
- // If the destination could not be determined, ignore.
- if err != nil || dst == nil {
+ dst := parseDstFromOOB(oob)
+ if dst == nil {
return nil
}
- return marshalUDPSocketSrc(dst)
+ // If the dst is definitely an IPv6, then use ipv6's ControlMessage to
+ // respond otherwise use ipv4's because ipv6's marshal ignores ipv4
+ // addresses.
+ if dst.To4() == nil {
+ cm := new(ipv6.ControlMessage)
+ cm.Src = dst
+ oob = cm.Marshal()
+ } else {
+ cm := new(ipv4.ControlMessage)
+ cm.Src = dst
+ oob = cm.Marshal()
+ }
+ return oob
}