1// +build !windows,!plan9 2 3package dns 4 5import ( 6 "net" 7 "syscall" 8) 9 10// SessionUDP holds the remote address and the associated 11// out-of-band data. 12type SessionUDP struct { 13 raddr *net.UDPAddr 14 context []byte 15} 16 17// RemoteAddr returns the remote network address. 18func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr } 19 20// setUDPSocketOptions sets the UDP socket options. 21// This function is implemented on a per platform basis. See udp_*.go for more details 22func setUDPSocketOptions(conn *net.UDPConn) error { 23 sa, err := getUDPSocketName(conn) 24 if err != nil { 25 return err 26 } 27 switch sa.(type) { 28 case *syscall.SockaddrInet6: 29 v6only, err := getUDPSocketOptions6Only(conn) 30 if err != nil { 31 return err 32 } 33 setUDPSocketOptions6(conn) 34 if !v6only { 35 setUDPSocketOptions4(conn) 36 } 37 case *syscall.SockaddrInet4: 38 setUDPSocketOptions4(conn) 39 } 40 return nil 41} 42 43// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a 44// net.UDPAddr. 45func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) { 46 oob := make([]byte, 40) 47 n, oobn, _, raddr, err := conn.ReadMsgUDP(b, oob) 48 if err != nil { 49 return n, nil, err 50 } 51 return n, &SessionUDP{raddr, oob[:oobn]}, err 52} 53 54// WriteToSessionUDP acts just like net.UDPConn.WritetTo(), but uses a *SessionUDP instead of a net.Addr. 55func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) { 56 n, _, err := conn.WriteMsgUDP(b, session.context, session.raddr) 57 return n, err 58} 59