payload_cmsg_go1_9.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. // Copyright 2017 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // +build go1.9
  5. // +build darwin dragonfly freebsd linux netbsd openbsd solaris
  6. package ipv4
  7. import (
  8. "net"
  9. "golang.org/x/net/internal/socket"
  10. )
  11. func (c *payloadHandler) readFrom(b []byte) (int, *ControlMessage, net.Addr, error) {
  12. c.rawOpt.RLock()
  13. m := socket.Message{
  14. OOB: NewControlMessage(c.rawOpt.cflags),
  15. }
  16. c.rawOpt.RUnlock()
  17. switch c.PacketConn.(type) {
  18. case *net.UDPConn:
  19. m.Buffers = [][]byte{b}
  20. if err := c.RecvMsg(&m, 0); err != nil {
  21. return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
  22. }
  23. case *net.IPConn:
  24. h := make([]byte, HeaderLen)
  25. m.Buffers = [][]byte{h, b}
  26. if err := c.RecvMsg(&m, 0); err != nil {
  27. return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
  28. }
  29. hdrlen := int(h[0]&0x0f) << 2
  30. if hdrlen > len(h) {
  31. d := hdrlen - len(h)
  32. copy(b, b[d:])
  33. m.N -= d
  34. } else {
  35. m.N -= hdrlen
  36. }
  37. default:
  38. return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: errInvalidConnType}
  39. }
  40. var cm *ControlMessage
  41. if m.NN > 0 {
  42. cm = new(ControlMessage)
  43. if err := cm.Parse(m.OOB[:m.NN]); err != nil {
  44. return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
  45. }
  46. cm.Src = netAddrToIP4(m.Addr)
  47. }
  48. return m.N, cm, m.Addr, nil
  49. }
  50. func (c *payloadHandler) writeTo(b []byte, cm *ControlMessage, dst net.Addr) (int, error) {
  51. m := socket.Message{
  52. Buffers: [][]byte{b},
  53. OOB: cm.Marshal(),
  54. Addr: dst,
  55. }
  56. err := c.SendMsg(&m, 0)
  57. if err != nil {
  58. err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Addr: opAddr(dst), Err: err}
  59. }
  60. return m.N, err
  61. }