1
0

udp_linux_64.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. //go:build linux && (amd64 || arm64 || ppc64 || ppc64le || mips64 || mips64le || s390x || riscv64 || loong64) && !android && !e2e_testing
  2. // +build linux
  3. // +build amd64 arm64 ppc64 ppc64le mips64 mips64le s390x riscv64 loong64
  4. // +build !android
  5. // +build !e2e_testing
  6. package udp
  7. import (
  8. "golang.org/x/sys/unix"
  9. )
  10. type iovec struct {
  11. Base *byte
  12. Len uint64
  13. }
  14. type msghdr struct {
  15. Name *byte
  16. Namelen uint32
  17. Pad0 [4]byte
  18. Iov *iovec
  19. Iovlen uint64
  20. Control *byte
  21. Controllen uint64
  22. Flags int32
  23. Pad1 [4]byte
  24. }
  25. type rawMessage struct {
  26. Hdr msghdr
  27. Len uint32
  28. Pad0 [4]byte
  29. }
  30. func (u *StdConn) PrepareRawMessages(n int) ([]rawMessage, [][]byte, [][]byte) {
  31. msgs := make([]rawMessage, n)
  32. buffers := make([][]byte, n)
  33. names := make([][]byte, n)
  34. for i := range msgs {
  35. buffers[i] = make([]byte, MTU)
  36. names[i] = make([]byte, unix.SizeofSockaddrInet6)
  37. vs := []iovec{
  38. {Base: &buffers[i][0], Len: uint64(len(buffers[i]))},
  39. }
  40. msgs[i].Hdr.Iov = &vs[0]
  41. msgs[i].Hdr.Iovlen = uint64(len(vs))
  42. msgs[i].Hdr.Name = &names[i][0]
  43. msgs[i].Hdr.Namelen = uint32(len(names[i]))
  44. }
  45. return msgs, buffers, names
  46. }
  47. // prepareWriteMessages allocates one Mmsghdr/iovec/sockaddr scratch per slot,
  48. // wired up so each writeMsgs[i] already points at writeIovs[i] and
  49. // writeNames[i]. Callers fill in the iovec Base/Len, the sockaddr bytes, and
  50. // Namelen before each sendmmsg.
  51. func (u *StdConn) prepareWriteMessages(n int) {
  52. u.writeMsgs = make([]rawMessage, n)
  53. u.writeIovs = make([]iovec, n)
  54. u.writeNames = make([][]byte, n)
  55. for i := range u.writeMsgs {
  56. u.writeNames[i] = make([]byte, unix.SizeofSockaddrInet6)
  57. u.writeMsgs[i].Hdr.Iov = &u.writeIovs[i]
  58. u.writeMsgs[i].Hdr.Iovlen = 1
  59. u.writeMsgs[i].Hdr.Name = &u.writeNames[i][0]
  60. }
  61. }
  62. func setIovLen(v *iovec, n int) {
  63. v.Len = uint64(n)
  64. }
  65. func setMsgIovlen(m *msghdr, n int) {
  66. m.Iovlen = uint64(n)
  67. }
  68. func setMsgControllen(m *msghdr, n int) {
  69. m.Controllen = uint64(n)
  70. }
  71. func setCmsgLen(h *unix.Cmsghdr, n int) {
  72. h.Len = uint64(n)
  73. }