conn.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package udp
  2. import (
  3. "net/netip"
  4. "github.com/slackhq/nebula/config"
  5. )
  6. const MTU = 9001
  7. // MaxWriteBatch is the largest batch any Conn.WriteBatch implementation is
  8. // required to accept. Callers SHOULD NOT pass more than this per call; Linux
  9. // backends preallocate sendmmsg scratch sized to this value, so exceeding it
  10. // only costs a chunked retry.
  11. const MaxWriteBatch = 128
  12. type EncReader func(
  13. addr netip.AddrPort,
  14. payload []byte,
  15. )
  16. type Conn interface {
  17. Rebind() error
  18. LocalAddr() (netip.AddrPort, error)
  19. // ListenOut invokes r for each received packet. On batch-capable
  20. // backends (recvmmsg), flush is called after each batch is fully
  21. // delivered — callers use it to flush per-batch accumulators such as
  22. // TUN write coalescers. Single-packet backends call flush after each
  23. // packet. flush must not be nil.
  24. ListenOut(r EncReader, flush func()) error
  25. WriteTo(b []byte, addr netip.AddrPort) error
  26. // WriteBatch sends a contiguous batch of packets, each with its own
  27. // destination. bufs and addrs must have the same length. Linux uses
  28. // sendmmsg(2) for a single syscall; other backends fall back to a
  29. // WriteTo loop. Returns on the first error; callers may observe a
  30. // partial send if some packets went out before the error.
  31. WriteBatch(bufs [][]byte, addrs []netip.AddrPort) error
  32. // WriteSegmented sends bufs as a single UDP GSO sendmsg when the kernel
  33. // supports it: all bufs go to the same addr, each must be exactly segSize
  34. // bytes except the last which may be shorter. The kernel emits one
  35. // datagram per buf on the wire. Backends / kernels without GSO support
  36. // fall back to a per-packet WriteTo loop. Returns on the first error.
  37. WriteSegmented(bufs [][]byte, addr netip.AddrPort, segSize int) error
  38. // SupportsGSO reports whether WriteSegmented takes the single-syscall
  39. // GSO path. Callers use this to decide at batch-assembly time whether
  40. // the uniform-size / same-dst check is worth running.
  41. SupportsGSO() bool
  42. ReloadConfig(c *config.C)
  43. SupportsMultipleReaders() bool
  44. Close() error
  45. }
  46. type NoopConn struct{}
  47. func (NoopConn) Rebind() error {
  48. return nil
  49. }
  50. func (NoopConn) LocalAddr() (netip.AddrPort, error) {
  51. return netip.AddrPort{}, nil
  52. }
  53. func (NoopConn) ListenOut(_ EncReader, _ func()) error {
  54. return nil
  55. }
  56. func (NoopConn) SupportsMultipleReaders() bool {
  57. return false
  58. }
  59. func (NoopConn) WriteTo(_ []byte, _ netip.AddrPort) error {
  60. return nil
  61. }
  62. func (NoopConn) WriteBatch(_ [][]byte, _ []netip.AddrPort) error {
  63. return nil
  64. }
  65. func (NoopConn) WriteSegmented(_ [][]byte, _ netip.AddrPort, _ int) error {
  66. return nil
  67. }
  68. func (NoopConn) SupportsGSO() bool {
  69. return false
  70. }
  71. func (NoopConn) ReloadConfig(_ *config.C) {
  72. return
  73. }
  74. func (NoopConn) Close() error {
  75. return nil
  76. }