reader_options.go 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*
  2. Copyright 2025 Psiphon Inc.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package udsipc
  14. import (
  15. "errors"
  16. "time"
  17. )
  18. // ReaderOption is the functional option type for Reader.
  19. type ReaderOption func(r *Reader) error
  20. // WithMaxMessageSize sets the maximum size for incoming messages.
  21. // Messages larger than this size will be rejected and cause the connection to close.
  22. // Default is 10MB.
  23. func WithMaxMessageSize(size uint64) ReaderOption {
  24. return func(r *Reader) error {
  25. r.maxMessageSize = size
  26. return nil
  27. }
  28. }
  29. // WithInactivityTimeout sets the timeout for connection inactivity.
  30. // If no message is received within this duration, the connection will timeout and close.
  31. // This timeout slides forward with each received message.
  32. // Default is 10 seconds.
  33. func WithInactivityTimeout(timeout time.Duration) ReaderOption {
  34. return func(r *Reader) error {
  35. if timeout <= 0 {
  36. return errors.Join(ErrInvalidTimeout, errors.New("inactivity timeout must be > 0"))
  37. }
  38. r.inactivityTimeout = timeout
  39. return nil
  40. }
  41. }
  42. // WithReaderErrorCallback sets the callback function for reader error notifications.
  43. // The callback receives detailed error information with context strings describing
  44. // where the error occurred (e.g., "failed to read the length prefix").
  45. // If nil, errors are not reported to the application.
  46. func WithReaderErrorCallback(callback ErrorCallback) ReaderOption {
  47. return func(r *Reader) error {
  48. r.onError = callback
  49. return nil
  50. }
  51. }
  52. // WithMaxAcceptErrors sets the maximum number of consecutive accept errors
  53. // before the reader stops accepting new connections.
  54. // This prevents infinite error loops when the listener is persistently failing.
  55. // Must be <= 63 to prevent overflow in exponential backoff calculation.
  56. // Default is 10.
  57. func WithMaxAcceptErrors(maxErrors int) ReaderOption {
  58. return func(r *Reader) error {
  59. if maxErrors > 63 { // nolint: mnd // See doc comment.
  60. return ErrMaxAcceptErrorsTooLarge
  61. }
  62. r.maxAcceptErrors = maxErrors
  63. return nil
  64. }
  65. }
  66. // WithReadBufferSize sets the kernel read buffer size (SO_RCVBUF).
  67. // Larger buffers can improve performance by reducing kernel memory allocation overhead.
  68. // Set to 0 to disable buffer size optimization and use system defaults.
  69. // Default is 256KB.
  70. func WithReadBufferSize(size uint32) ReaderOption {
  71. return func(r *Reader) error {
  72. r.readBufferSize = size
  73. return nil
  74. }
  75. }