udp_linux_64.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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, [][]byte) {
  31. msgs := make([]rawMessage, n)
  32. buffers := make([][]byte, n)
  33. names := make([][]byte, n)
  34. controls := make([][]byte, n)
  35. // Use larger buffers if GRO is enabled to hold coalesced packets
  36. bufSize := MTU
  37. if u.groSupported {
  38. bufSize = groMaxPacketSize
  39. }
  40. // Control buffer size for receiving UDP_GRO segment size
  41. controlSize := 0
  42. if u.groSupported {
  43. controlSize = unix.CmsgSpace(2) // space for uint16 segment size
  44. }
  45. for i := range msgs {
  46. buffers[i] = make([]byte, bufSize)
  47. names[i] = make([]byte, unix.SizeofSockaddrInet6)
  48. vs := []iovec{
  49. {Base: &buffers[i][0], Len: uint64(len(buffers[i]))},
  50. }
  51. msgs[i].Hdr.Iov = &vs[0]
  52. msgs[i].Hdr.Iovlen = uint64(len(vs))
  53. msgs[i].Hdr.Name = &names[i][0]
  54. msgs[i].Hdr.Namelen = uint32(len(names[i]))
  55. // Set up control message buffer for GRO
  56. if controlSize > 0 {
  57. controls[i] = make([]byte, controlSize)
  58. msgs[i].Hdr.Control = &controls[i][0]
  59. msgs[i].Hdr.Controllen = uint64(controlSize)
  60. }
  61. }
  62. return msgs, buffers, names, controls
  63. }
  64. func setIovecBase(iov *iovec, base *byte) {
  65. iov.Base = base
  66. }
  67. func setIovecLen(iov *iovec, l int) {
  68. iov.Len = uint64(l)
  69. }
  70. func setMsghdrIovlen(hdr *msghdr, l int) {
  71. hdr.Iovlen = uint64(l)
  72. }
  73. func setMsghdrControllen(hdr *msghdr, l int) {
  74. hdr.Controllen = uint64(l)
  75. }
  76. func getMsghdrControllen(hdr *msghdr) int {
  77. return int(hdr.Controllen)
  78. }