config.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. package quic
  2. import (
  3. "fmt"
  4. "time"
  5. "github.com/Psiphon-Labs/quic-go/internal/protocol"
  6. "github.com/Psiphon-Labs/quic-go/quicvarint"
  7. )
  8. // Clone clones a Config
  9. func (c *Config) Clone() *Config {
  10. copy := *c
  11. return &copy
  12. }
  13. func (c *Config) handshakeTimeout() time.Duration {
  14. return 2 * c.HandshakeIdleTimeout
  15. }
  16. func (c *Config) maxRetryTokenAge() time.Duration {
  17. return c.handshakeTimeout()
  18. }
  19. func validateConfig(config *Config) error {
  20. if config == nil {
  21. return nil
  22. }
  23. const maxStreams = 1 << 60
  24. if config.MaxIncomingStreams > maxStreams {
  25. config.MaxIncomingStreams = maxStreams
  26. }
  27. if config.MaxIncomingUniStreams > maxStreams {
  28. config.MaxIncomingUniStreams = maxStreams
  29. }
  30. if config.MaxStreamReceiveWindow > quicvarint.Max {
  31. config.MaxStreamReceiveWindow = quicvarint.Max
  32. }
  33. if config.MaxConnectionReceiveWindow > quicvarint.Max {
  34. config.MaxConnectionReceiveWindow = quicvarint.Max
  35. }
  36. if config.InitialPacketSize > 0 && config.InitialPacketSize < protocol.MinInitialPacketSize {
  37. config.InitialPacketSize = protocol.MinInitialPacketSize
  38. }
  39. if config.InitialPacketSize > protocol.MaxPacketBufferSize {
  40. config.InitialPacketSize = protocol.MaxPacketBufferSize
  41. }
  42. // check that all QUIC versions are actually supported
  43. for _, v := range config.Versions {
  44. if !protocol.IsValidVersion(v) {
  45. return fmt.Errorf("invalid QUIC version: %s", v)
  46. }
  47. }
  48. return nil
  49. }
  50. // populateConfig populates fields in the quic.Config with their default values, if none are set
  51. // it may be called with nil
  52. func populateConfig(config *Config) *Config {
  53. if config == nil {
  54. config = &Config{}
  55. }
  56. versions := config.Versions
  57. if len(versions) == 0 {
  58. versions = protocol.SupportedVersions
  59. }
  60. handshakeIdleTimeout := protocol.DefaultHandshakeIdleTimeout
  61. if config.HandshakeIdleTimeout != 0 {
  62. handshakeIdleTimeout = config.HandshakeIdleTimeout
  63. }
  64. idleTimeout := protocol.DefaultIdleTimeout
  65. if config.MaxIdleTimeout != 0 {
  66. idleTimeout = config.MaxIdleTimeout
  67. }
  68. initialStreamReceiveWindow := config.InitialStreamReceiveWindow
  69. if initialStreamReceiveWindow == 0 {
  70. initialStreamReceiveWindow = protocol.DefaultInitialMaxStreamData
  71. }
  72. maxStreamReceiveWindow := config.MaxStreamReceiveWindow
  73. if maxStreamReceiveWindow == 0 {
  74. maxStreamReceiveWindow = protocol.DefaultMaxReceiveStreamFlowControlWindow
  75. }
  76. initialConnectionReceiveWindow := config.InitialConnectionReceiveWindow
  77. if initialConnectionReceiveWindow == 0 {
  78. initialConnectionReceiveWindow = protocol.DefaultInitialMaxData
  79. }
  80. maxConnectionReceiveWindow := config.MaxConnectionReceiveWindow
  81. if maxConnectionReceiveWindow == 0 {
  82. maxConnectionReceiveWindow = protocol.DefaultMaxReceiveConnectionFlowControlWindow
  83. }
  84. maxIncomingStreams := config.MaxIncomingStreams
  85. if maxIncomingStreams == 0 {
  86. maxIncomingStreams = protocol.DefaultMaxIncomingStreams
  87. } else if maxIncomingStreams < 0 {
  88. maxIncomingStreams = 0
  89. }
  90. maxIncomingUniStreams := config.MaxIncomingUniStreams
  91. if maxIncomingUniStreams == 0 {
  92. maxIncomingUniStreams = protocol.DefaultMaxIncomingUniStreams
  93. } else if maxIncomingUniStreams < 0 {
  94. maxIncomingUniStreams = 0
  95. }
  96. initialPacketSize := config.InitialPacketSize
  97. if initialPacketSize == 0 {
  98. initialPacketSize = protocol.InitialPacketSize
  99. }
  100. return &Config{
  101. GetConfigForClient: config.GetConfigForClient,
  102. Versions: versions,
  103. HandshakeIdleTimeout: handshakeIdleTimeout,
  104. MaxIdleTimeout: idleTimeout,
  105. KeepAlivePeriod: config.KeepAlivePeriod,
  106. InitialStreamReceiveWindow: initialStreamReceiveWindow,
  107. MaxStreamReceiveWindow: maxStreamReceiveWindow,
  108. InitialConnectionReceiveWindow: initialConnectionReceiveWindow,
  109. MaxConnectionReceiveWindow: maxConnectionReceiveWindow,
  110. AllowConnectionWindowIncrease: config.AllowConnectionWindowIncrease,
  111. MaxIncomingStreams: maxIncomingStreams,
  112. MaxIncomingUniStreams: maxIncomingUniStreams,
  113. TokenStore: config.TokenStore,
  114. EnableDatagrams: config.EnableDatagrams,
  115. InitialPacketSize: initialPacketSize,
  116. DisablePathMTUDiscovery: config.DisablePathMTUDiscovery,
  117. Allow0RTT: config.Allow0RTT,
  118. Tracer: config.Tracer,
  119. // [Psiphon]
  120. ClientHelloSeed: config.ClientHelloSeed,
  121. GetClientHelloRandom: config.GetClientHelloRandom,
  122. VerifyClientHelloRandom: config.VerifyClientHelloRandom,
  123. ClientMaxPacketSizeAdjustment: config.ClientMaxPacketSizeAdjustment,
  124. ServerMaxPacketSizeAdjustment: config.ServerMaxPacketSizeAdjustment,
  125. }
  126. }