diff --git a/udp.go b/udp.go index fc865637..c79c6c88 100644 --- a/udp.go +++ b/udp.go @@ -1,4 +1,4 @@ -// +build !windows +// +build !windows,!plan9 package dns diff --git a/udp_other.go b/udp_other.go index c38dd3e7..d4073244 100644 --- a/udp_other.go +++ b/udp_other.go @@ -1,4 +1,4 @@ -// +build !linux +// +build !linux,!plan9 package dns diff --git a/udp_plan9.go b/udp_plan9.go new file mode 100644 index 00000000..b794deeb --- /dev/null +++ b/udp_plan9.go @@ -0,0 +1,34 @@ +package dns + +import ( + "net" +) + +func setUDPSocketOptions(conn *net.UDPConn) error { return nil } + +// SessionUDP holds the remote address and the associated +// out-of-band data. +type SessionUDP struct { + raddr *net.UDPAddr + context []byte +} + +// RemoteAddr returns the remote network address. +func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr } + +// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a +// net.UDPAddr. +func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) { + oob := make([]byte, 40) + n, oobn, _, raddr, err := conn.ReadMsgUDP(b, oob) + if err != nil { + return n, nil, err + } + return n, &SessionUDP{raddr, oob[:oobn]}, err +} + +// WriteToSessionUDP acts just like net.UDPConn.WritetTo(), but uses a *SessionUDP instead of a net.Addr. +func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) { + n, _, err := conn.WriteMsgUDP(b, session.context, session.raddr) + return n, err +}