udp.go 1.5 KB

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