@@ -29,82 +29,101 @@ type Quic struct {
29
29
IPv6 bool
30
30
}
31
31
32
- func (q * Quic ) Update (k store.K8s , h haproxy.HAProxy , a annotations.Annotations ) (err error ) {
33
- var errs utils.Errors
34
- defer func () {
35
- err = errs .Result ()
36
- }()
37
- var bindv4Present , bindv6Present bool
38
- binds , errBindsGet := h .FrontendBindsGet (h .FrontHTTPS )
39
- if errBindsGet != nil {
40
- errs .Add (errBindsGet )
32
+ func (q * Quic ) enableQuic (h haproxy.HAProxy ) (err error ) {
33
+ var binds []models.Bind
34
+ var bindIPv4Exists , bindIPv6Exists bool
35
+
36
+ err = q .altSvcRule (h )
37
+ if err != nil {
41
38
return
42
39
}
43
40
44
- for _ , bind := range binds {
45
- bindv4Present = bindv4Present || bind . Name == QUIC4BIND
46
- bindv6Present = bindv6Present || bind . Name == QUIC6BIND
41
+ existingBinds , err := h . FrontendBindsGet ( h . FrontHTTPS )
42
+ if err != nil {
43
+ return
47
44
}
48
45
49
- ipv4Func := func () {
50
- if bindv4Present {
51
- return
46
+ if q .IPv4 || q .IPv6 {
47
+ for _ , existingBind := range existingBinds {
48
+ if existingBind .Name == QUIC4BIND {
49
+ bindIPv4Exists = true
50
+ }
51
+ if existingBind .Name == QUIC6BIND {
52
+ bindIPv6Exists = true
53
+ }
52
54
}
55
+ }
53
56
54
- errFrontendBindCreate := h .FrontendBindCreate (h .FrontHTTPS , models.Bind {
55
- Address : func () (addr string ) {
56
- addr = "quic4@" + q .AddrIPv4
57
- return
58
- }(),
59
- Port : utils .PtrInt64 (q .QuicBindPort ),
57
+ addBind := func (addr string , bindName string , v4v6 bool ) {
58
+ binds = append (binds , models.Bind {
59
+ Address : addr ,
60
+ Port : utils .PtrInt64 (q .QuicBindPort ),
60
61
BindParams : models.BindParams {
61
- Name : QUIC4BIND ,
62
+ Name : bindName ,
62
63
Ssl : true ,
63
64
SslCertificate : q .CertDir ,
64
65
Alpn : "h3" ,
66
+ V4v6 : v4v6 ,
65
67
},
66
68
})
67
- errs .Add (errFrontendBindCreate )
68
- instance .ReloadIf (errFrontendBindCreate == nil , "quic binding v4 created" )
69
69
}
70
70
71
- ipv6Func := func () {
72
- if bindv6Present {
73
- return
74
- }
75
- errFrontendBindCreate := h .FrontendBindCreate (h .FrontHTTPS , models.Bind {
76
- Address : func () (addr string ) {
77
- addr = "quic6@" + q .AddrIPv6
78
- return
79
- }(),
80
- Port : utils .PtrInt64 (q .QuicBindPort ),
81
- BindParams : models.BindParams {
82
- Name : QUIC6BIND ,
83
- Ssl : true ,
84
- SslCertificate : q .CertDir ,
85
- Alpn : "h3" ,
86
- },
87
- })
88
- errs .Add (errFrontendBindCreate )
89
- instance .ReloadIf (errFrontendBindCreate == nil , "quic binding v6 created" )
71
+ if q .IPv4 && ! bindIPv4Exists {
72
+ addBind ("quic4@" + q .AddrIPv4 , QUIC4BIND , false )
73
+ }
74
+ if q .IPv6 && ! bindIPv6Exists {
75
+ addBind ("quic6@" + q .AddrIPv6 , QUIC6BIND , true )
90
76
}
91
77
92
- ipv4DeleteFunc := func () {
93
- if ! bindv4Present {
94
- return
78
+ for _ , bind := range binds {
79
+ err = h .FrontendBindCreate (h .FrontHTTPS , bind )
80
+ if err != nil {
81
+ return err
95
82
}
96
- errFrontendBindDelete := h .FrontendBindDelete (h .FrontHTTPS , QUIC4BIND )
97
- errs .Add (errFrontendBindDelete )
98
- instance .ReloadIf (errFrontendBindDelete == nil , "quic binding v4 removed" )
99
83
}
100
84
101
- ipv6DeleteFunc := func () {
102
- if ! bindv6Present {
103
- return
85
+ if len (binds ) > 0 {
86
+ instance .Reload ("QUIC enabled" )
87
+ }
88
+ return
89
+ }
90
+
91
+ func (q * Quic ) disableQuic (h haproxy.HAProxy ) (err error ) {
92
+ errors := utils.Errors {}
93
+ if q .IPv6 {
94
+ errors .Add (h .FrontendBindDelete (h .FrontHTTPS , QUIC6BIND ))
95
+ }
96
+ if q .IPv4 {
97
+ errors .Add (h .FrontendBindDelete (h .FrontHTTPS , QUIC4BIND ))
98
+ }
99
+ err = errors .Result ()
100
+ if err == nil {
101
+ instance .Reload ("QUIC disabled" )
102
+ }
103
+ return
104
+ }
105
+
106
+ func (q * Quic ) altSvcRule (h haproxy.HAProxy ) (err error ) {
107
+ errors := utils.Errors {}
108
+ logger .Debug ("quic redirect rule to be created" )
109
+ errors .Add (h .AddRule (h .FrontHTTPS , rules.RequestRedirectQuic {}, false ))
110
+ logger .Debug ("quic set header rule to be created" )
111
+ errors .Add (h .AddRule (h .FrontHTTPS , rules.SetHdr {
112
+ HdrName : "alt-svc" ,
113
+ Response : true ,
114
+ HdrFormat : fmt .Sprintf ("\" h3=\\ \" :%d\\ \" ; ma=" + q .MaxAge + "\" " , q .QuicAnnouncePort ),
115
+ }, false ))
116
+ return errors .Result ()
117
+ }
118
+
119
+ func (q * Quic ) Update (k store.K8s , h haproxy.HAProxy , a annotations.Annotations ) (err error ) {
120
+ sslOffloadEnabled := h .FrontendSSLOffloadEnabled (h .FrontHTTPS )
121
+ if ! sslOffloadEnabled {
122
+ logger .Warning ("quic requires SSL offload to be enabled" )
123
+ if err := q .disableQuic (h ); err != nil {
124
+ return err
104
125
}
105
- errFrontendBindDelete := h .FrontendBindDelete (h .FrontHTTPS , QUIC6BIND )
106
- errs .Add (errFrontendBindDelete )
107
- instance .ReloadIf (errFrontendBindDelete == nil , "quic binding v6 removed" )
126
+ return nil
108
127
}
109
128
110
129
maxAge := common .GetValue ("quic-alt-svc-max-age" , k .ConfigMaps .Main .Annotations )
@@ -116,38 +135,25 @@ func (q *Quic) Update(k store.K8s, h haproxy.HAProxy, a annotations.Annotations)
116
135
117
136
nsSslCertificateAnn , nameSslCertificateAnn , err := common .GetK8sPath ("ssl-certificate" , k .ConfigMaps .Main .Annotations )
118
137
if err != nil || (nameSslCertificateAnn == "" ) {
119
- errs .Add (err )
120
- ipv4Func = ipv4DeleteFunc
121
- ipv6Func = ipv6DeleteFunc
122
- } else {
123
- namespaceSslCertificate := k .Namespaces [nsSslCertificateAnn ]
124
- var sslSecret * store.Secret
125
- if namespaceSslCertificate != nil {
126
- sslSecret = namespaceSslCertificate .Secret [nameSslCertificateAnn ]
127
- }
128
-
129
- if sslSecret == nil || sslSecret .Status == store .DELETED {
130
- ipv4Func = ipv4DeleteFunc
131
- ipv6Func = ipv6DeleteFunc
132
- } else {
133
- logger .Debug ("quic redirect rule to be created" )
134
- errs .Add (h .AddRule (h .FrontHTTPS , rules.RequestRedirectQuic {}, false ))
135
- logger .Debug ("quic set header rule to be created" )
136
- errs .Add (h .AddRule (h .FrontHTTPS , rules.SetHdr {
137
- HdrName : "alt-svc" ,
138
- Response : true ,
139
- HdrFormat : fmt .Sprintf ("\" h3=\\ \" :%d\\ \" ;ma=" + maxAge + ";\" " , q .QuicAnnouncePort ),
140
- }, false ))
138
+ if err := q .disableQuic (h ); err != nil {
139
+ return err
141
140
}
141
+ return nil
142
142
}
143
143
144
- if q .IPv4 {
145
- ipv4Func ()
144
+ namespaceSslCertificate := k .Namespaces [nsSslCertificateAnn ]
145
+ var sslSecret * store.Secret
146
+ if namespaceSslCertificate != nil {
147
+ sslSecret = namespaceSslCertificate .Secret [nameSslCertificateAnn ]
146
148
}
147
149
148
- if q .IPv6 {
149
- ipv6Func ()
150
+ if sslSecret == nil || sslSecret .Status == store .DELETED {
151
+ logger .Warning ("quic requires valid and existing ssl-certificate" )
152
+ if err := q .disableQuic (h ); err != nil {
153
+ return err
154
+ }
155
+ return nil
150
156
}
151
157
152
- return
158
+ return q . enableQuic ( h )
153
159
}
0 commit comments