1package quic
2
3import (
4	"errors"
5
6	"github.com/lucas-clemente/quic-go/internal/protocol"
7)
8
9// Clone clones a Config
10func (c *Config) Clone() *Config {
11	copy := *c
12	return &copy
13}
14
15func validateConfig(config *Config) error {
16	if config == nil {
17		return nil
18	}
19	if config.MaxIncomingStreams > 1<<60 {
20		return errors.New("invalid value for Config.MaxIncomingStreams")
21	}
22	if config.MaxIncomingUniStreams > 1<<60 {
23		return errors.New("invalid value for Config.MaxIncomingUniStreams")
24	}
25	return nil
26}
27
28// populateServerConfig populates fields in the quic.Config with their default values, if none are set
29// it may be called with nil
30func populateServerConfig(config *Config) *Config {
31	config = populateConfig(config)
32	if config.ConnectionIDLength == 0 {
33		config.ConnectionIDLength = protocol.DefaultConnectionIDLength
34	}
35	if config.AcceptToken == nil {
36		config.AcceptToken = defaultAcceptToken
37	}
38	return config
39}
40
41// populateClientConfig populates fields in the quic.Config with their default values, if none are set
42// it may be called with nil
43func populateClientConfig(config *Config, createdPacketConn bool) *Config {
44	config = populateConfig(config)
45	if config.ConnectionIDLength == 0 && !createdPacketConn {
46		config.ConnectionIDLength = protocol.DefaultConnectionIDLength
47	}
48	return config
49}
50
51func populateConfig(config *Config) *Config {
52	if config == nil {
53		config = &Config{}
54	}
55	versions := config.Versions
56	if len(versions) == 0 {
57		versions = protocol.SupportedVersions
58	}
59	handshakeTimeout := protocol.DefaultHandshakeTimeout
60	if config.HandshakeTimeout != 0 {
61		handshakeTimeout = config.HandshakeTimeout
62	}
63	idleTimeout := protocol.DefaultIdleTimeout
64	if config.MaxIdleTimeout != 0 {
65		idleTimeout = config.MaxIdleTimeout
66	}
67	maxReceiveStreamFlowControlWindow := config.MaxReceiveStreamFlowControlWindow
68	if maxReceiveStreamFlowControlWindow == 0 {
69		maxReceiveStreamFlowControlWindow = protocol.DefaultMaxReceiveStreamFlowControlWindow
70	}
71	maxReceiveConnectionFlowControlWindow := config.MaxReceiveConnectionFlowControlWindow
72	if maxReceiveConnectionFlowControlWindow == 0 {
73		maxReceiveConnectionFlowControlWindow = protocol.DefaultMaxReceiveConnectionFlowControlWindow
74	}
75	maxIncomingStreams := config.MaxIncomingStreams
76	if maxIncomingStreams == 0 {
77		maxIncomingStreams = protocol.DefaultMaxIncomingStreams
78	} else if maxIncomingStreams < 0 {
79		maxIncomingStreams = 0
80	}
81	maxIncomingUniStreams := config.MaxIncomingUniStreams
82	if maxIncomingUniStreams == 0 {
83		maxIncomingUniStreams = protocol.DefaultMaxIncomingUniStreams
84	} else if maxIncomingUniStreams < 0 {
85		maxIncomingUniStreams = 0
86	}
87
88	return &Config{
89		Versions:                              versions,
90		HandshakeTimeout:                      handshakeTimeout,
91		MaxIdleTimeout:                        idleTimeout,
92		AcceptToken:                           config.AcceptToken,
93		KeepAlive:                             config.KeepAlive,
94		MaxReceiveStreamFlowControlWindow:     maxReceiveStreamFlowControlWindow,
95		MaxReceiveConnectionFlowControlWindow: maxReceiveConnectionFlowControlWindow,
96		MaxIncomingStreams:                    maxIncomingStreams,
97		MaxIncomingUniStreams:                 maxIncomingUniStreams,
98		ConnectionIDLength:                    config.ConnectionIDLength,
99		StatelessResetKey:                     config.StatelessResetKey,
100		TokenStore:                            config.TokenStore,
101		QuicTracer:                            config.QuicTracer,
102		Tracer:                                config.Tracer,
103	}
104}
105