github.com/MerlinKodo/quic-go@v0.39.2/config.go (about)

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