AlinsRan commented on code in PR #2882:
URL: 
https://github.com/apache/apisix-ingress-controller/pull/2882#discussion_r4244312534


##########
internal/controller/utils.go:
##########
@@ -1392,30 +1392,56 @@ func FullTypeName(a any) string {
 // filterHostnames accepts a list of gateways and an HTTPRoute, and returns a 
copy of the HTTPRoute with only the hostnames that match the listener hostnames 
of the gateways.
 // If the HTTPRoute hostnames do not intersect with the listener hostnames of 
the gateways, it returns an ErrNoMatchingListenerHostname error.
 func filterHostnames(gateways []RouteParentRefContext, httpRoute 
*gatewayv1.HTTPRoute) (*gatewayv1.HTTPRoute, error) {
-       filteredHostnames := make([]gatewayv1.Hostname, 0)
+       hostnames, err := intersectRouteHostnames(gateways, 
httpRoute.Spec.Hostnames)
+       if err != nil {
+               return httpRoute, err
+       }
+       httpRoute.Spec.Hostnames = hostnames
+       return httpRoute, nil
+}
+
+// filterTLSRouteHostnames is filterHostnames for a TLSRoute. Its hostnames 
become
+// the SNIs the stream routes match on, so a route left carrying its own 
broader
+// hostname would serve names the listener it attached to never accepted - 
and, on
+// a single shared stream listen, would take them from the route that should 
have.
+func filterTLSRouteHostnames(gateways []RouteParentRefContext, tlsRoute 
*gatewayv1.TLSRoute) (*gatewayv1.TLSRoute, error) {
+       hostnames, err := intersectRouteHostnames(gateways, 
tlsRoute.Spec.Hostnames)

Review Comment:
   Fixed in 284fa5da. The single-result lookup is replaced by one that collects 
every intersection:
   
   ```go
   // internal/controller/utils/hostname.go
   func NarrowHostname(listeners []gatewayv1.Listener, routeHostname 
gatewayv1.Hostname) []gatewayv1.Hostname {
        narrowed := make([]gatewayv1.Hostname, 0, len(listeners))
        for _, listener := range listeners {
                if listener.Hostname == nil || *listener.Hostname == "" ||
                        HostnamesMatch(string(*listener.Hostname), 
string(routeHostname)) {
                        return []gatewayv1.Hostname{routeHostname}
                }
                if HostnamesMatch(string(routeHostname), 
string(*listener.Hostname)) {
                        narrowed = append(narrowed, *listener.Hostname)
                }
        }
        return narrowed
   }
   ```
   
   A listener that accepts the route hostname whole still short-circuits, since 
that is the widest intersection available; otherwise every listener hostname 
the route hostname covers is kept, and `intersectRouteHostnames` de-duplicates 
the result because listeners are aggregated across Gateways without 
de-duplication.
   
   HTTPRoute goes through the same function, so this closes the gap there too. 
The matchers moved to `internal/controller/utils` so the translator can reuse 
them for the per-port SNI derivation instead of re-implementing wildcard 
matching.
   
   `TestIntersectRouteHostnamesKeepsEveryIntersection` is exactly your 
`*.example.com` over `a.example.com` + `b.example.com` case, and 
`TestTranslateTLSRouteSNIsPerPort/one_port_with_several_listeners_keeps_every_intersection`
 checks it reaches the SNIs. Restoring the early return makes both fail.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to