Skip to content

Commit 8a2a553

Browse files
committed
Clarify Gateway Listener Distinct definitions
Signed-off-by: Nick Young <[email protected]>
1 parent 3422b2f commit 8a2a553

File tree

4 files changed

+326
-186
lines changed

4 files changed

+326
-186
lines changed

apis/v1/gateway_types.go

Lines changed: 65 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ type GatewaySpec struct {
6969
// logical endpoints that are bound on this Gateway's addresses.
7070
// At least one Listener MUST be specified.
7171
//
72+
// ## Distinct Listeners
73+
//
7274
// Each Listener in a set of Listeners (for example, in a single Gateway)
7375
// MUST be _distinct_, in that a traffic flow MUST be able to be assigned to
7476
// exactly one listener. (This section uses "set of Listeners" rather than
@@ -80,74 +82,91 @@ type GatewaySpec struct {
8082
// combination of Port, Protocol, and, if supported by the protocol, Hostname.
8183
//
8284
// Some combinations of port, protocol, and TLS settings are considered
83-
// Core support and MUST be supported by implementations based on their
84-
// targeted conformance profile:
85+
// Core support and MUST be supported by implementations based on the objects
86+
// they support:
8587
//
86-
// HTTP Profile
88+
// HTTPRoute
8789
//
8890
// 1. HTTPRoute, Port: 80, Protocol: HTTP
8991
// 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate, TLS keypair provided
9092
//
91-
// TLS Profile
93+
// TLSRoute
9294
//
9395
// 1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough
9496
//
9597
// "Distinct" Listeners have the following property:
9698
//
97-
// The implementation can match inbound requests to a single distinct
98-
// Listener. When multiple Listeners share values for fields (for
99+
// **The implementation can match inbound requests to a single distinct
100+
// Listener**.
101+
//
102+
// When multiple Listeners share values for fields (for
99103
// example, two Listeners with the same Port value), the implementation
100104
// can match requests to only one of the Listeners using other
101105
// Listener fields.
102106
//
103-
// For example, the following Listener scenarios are distinct:
107+
// When multiple listeners have the same value for the Protocol field, then
108+
// each of the Listeners with matching Protocol values MUST have different
109+
// values for other fields.
110+
//
111+
// The set of fields that MUST be different for a Listener differs per protocol.
112+
// The following rules define the rules for what fields MUST be considered for
113+
// Listeners to be distinct with each protocol currently defined in the
114+
// Gateway API spec.
104115
//
105-
// 1. Multiple Listeners with the same Port that all use the "HTTP"
106-
// Protocol that all have unique Hostname values.
107-
// 2. Multiple Listeners with the same Port that use either the "HTTPS" or
108-
// "TLS" Protocol that all have unique Hostname values.
109-
// 3. A mixture of "TCP" and "UDP" Protocol Listeners, where no Listener
110-
// with the same Protocol has the same Port value.
116+
// The set of listeners that all share a protocol value MUST have _different_
117+
// values for _at least one_ of these fields to be distinct:
111118
//
112-
// Some fields in the Listener struct have possible values that affect
113-
// whether the Listener is distinct. Hostname is particularly relevant
114-
// for HTTP or HTTPS protocols.
119+
// * **HTTP**: Port, Hostname
120+
// * **HTTPS**: Port, Hostname
121+
// * **TLS**: Port, Hostname
122+
// * **TCP**: Port,
123+
// * **UDP**: Port
115124
//
116-
// When using the Hostname value to select between same-Port, same-Protocol
117-
// Listeners, the Hostname value must be different on each Listener for the
118-
// Listener to be distinct.
125+
// Note that TLS is not used for determining if a listener is distinct, because
126+
// Listeners that _only_ differ on TLS config will still conflict in all cases.
119127
//
120-
// When the Listeners are distinct based on Hostname, inbound request
128+
// ### Listeners that are distinct only by Hostname
129+
//
130+
// When the Listeners are distinct based only on Hostname, inbound request
121131
// hostnames MUST match from the most specific to least specific Hostname
122132
// values to choose the correct Listener and its associated set of Routes.
123133
//
124-
// Exact matches must be processed before wildcard matches, and wildcard
125-
// matches must be processed before fallback (empty Hostname value)
134+
// Exact matches MUST be processed before wildcard matches, and wildcard
135+
// matches MUST be processed before fallback (empty Hostname value)
126136
// matches. For example, `"foo.example.com"` takes precedence over
127137
// `"*.example.com"`, and `"*.example.com"` takes precedence over `""`.
128138
//
129139
// Additionally, if there are multiple wildcard entries, more specific
130140
// wildcard entries must be processed before less specific wildcard entries.
131141
// For example, `"*.foo.example.com"` takes precedence over `"*.example.com"`.
142+
//
132143
// The precise definition here is that the higher the number of dots in the
133144
// hostname to the right of the wildcard character, the higher the precedence.
134145
//
135146
// The wildcard character will match any number of characters _and dots_ to
136147
// the left, however, so `"*.example.com"` will match both
137148
// `"foo.bar.example.com"` _and_ `"bar.example.com"`.
138149
//
150+
// ## Handling indistinct Listeners
151+
//
139152
// If a set of Listeners contains Listeners that are not distinct, then those
140-
// Listeners are Conflicted, and the implementation MUST set the "Conflicted"
153+
// Listeners are _Conflicted_, and the implementation MUST set the "Conflicted"
141154
// condition in the Listener Status to "True".
142155
//
156+
// The words "indistict" and "conflicted" are considered synonyms for the
157+
// purpose of this documentation.
158+
//
143159
// Implementations MAY choose to accept a Gateway with some Conflicted
144160
// Listeners only if they only accept the partial Listener set that contains
145-
// no Conflicted Listeners. To put this another way, implementations may
146-
// accept a partial Listener set only if they throw out *all* the conflicting
147-
// Listeners. No picking one of the conflicting listeners as the winner.
148-
// This also means that the Gateway must have at least one non-conflicting
149-
// Listener in this case, otherwise it violates the requirement that at
150-
// least one Listener must be present.
161+
// no Conflicted Listeners.
162+
//
163+
// Specifically, an implementation MAY accept a partial Listener set subject to
164+
// the following rules:
165+
//
166+
// * The implementation MUST NOT pick one conflicting Listener as the winner.
167+
// ALL indistinct Listeners must not be accepted for processing.
168+
// * At least one distinct Listener MUST be present, or else the Gateway effectively
169+
// contains _no_ Listeners, and must be rejected from processing as a whole.
151170
//
152171
// The implementation MUST set a "ListenersNotValid" condition on the
153172
// Gateway Status when the Gateway contains Conflicted Listeners whether or
@@ -156,7 +175,23 @@ type GatewaySpec struct {
156175
// Accepted. Additionally, the Listener status for those listeners SHOULD
157176
// indicate which Listeners are conflicted and not Accepted.
158177
//
159-
// A Gateway's Listeners are considered "compatible" if:
178+
// ## General Listener behavior
179+
//
180+
// Note that, for all distinct Listeners, requests SHOULD match at most one Listener.
181+
// For example, if Listeners are defined for "foo.example.com" and "*.example.com", a
182+
// request to "foo.example.com" SHOULD only be routed using routes attached
183+
// to the "foo.example.com" Listener (and not the "*.example.com" Listener).
184+
//
185+
// This concept is known as "Listener Isolation". Implementations that do
186+
// not support Listener Isolation MUST clearly document this, and MUST NOT
187+
// claim support for the `GatewayHTTPListenerIsolation` feature.
188+
//
189+
// Implementations that _do_ support Listener Isolation SHOULD claim support
190+
// for the `GatewayHTTPListenerIsolation` feature and pass the associated conformance tests.
191+
//
192+
// ## Compatible Listeners
193+
//
194+
// A Gateway's Listeners are considered _compatible_ if:
160195
//
161196
// 1. They are distinct.
162197
// 2. The implementation can serve them in compliance with the Addresses
@@ -171,13 +206,6 @@ type GatewaySpec struct {
171206
// on the same address, or cannot mix HTTPS and generic TLS listens on the same port
172207
// would not consider those cases compatible, even though they are distinct.
173208
//
174-
// Note that requests SHOULD match at most one Listener. For example, if
175-
// Listeners are defined for "foo.example.com" and "*.example.com", a
176-
// request to "foo.example.com" SHOULD only be routed using routes attached
177-
// to the "foo.example.com" Listener (and not the "*.example.com" Listener).
178-
// This concept is known as "Listener Isolation". Implementations that do
179-
// not support Listener Isolation MUST clearly document this.
180-
//
181209
// Implementations MAY merge separate Gateways onto a single set of
182210
// Addresses if all Listeners across all Gateways are compatible.
183211
//

0 commit comments

Comments
 (0)