diff --git a/xds/src/main/java/io/grpc/xds/EnvoyServerProtoData.java b/xds/src/main/java/io/grpc/xds/EnvoyServerProtoData.java index 5ed0557df0..b8a5bfd290 100644 --- a/xds/src/main/java/io/grpc/xds/EnvoyServerProtoData.java +++ b/xds/src/main/java/io/grpc/xds/EnvoyServerProtoData.java @@ -228,6 +228,8 @@ public final class EnvoyServerProtoData { private final List sourcePrefixRanges; private final ConnectionSourceType sourceType; private final List sourcePorts; + private final List serverNames; + private final String transportProtocol; @VisibleForTesting FilterChainMatch( @@ -236,13 +238,17 @@ public final class EnvoyServerProtoData { List applicationProtocols, List sourcePrefixRanges, ConnectionSourceType sourceType, - List sourcePorts) { + List sourcePorts, + List serverNames, + String transportProtocol) { this.destinationPort = destinationPort; this.prefixRanges = Collections.unmodifiableList(prefixRanges); this.applicationProtocols = Collections.unmodifiableList(applicationProtocols); this.sourcePrefixRanges = sourcePrefixRanges; this.sourceType = sourceType; this.sourcePorts = sourcePorts; + this.serverNames = Collections.unmodifiableList(serverNames); + this.transportProtocol = transportProtocol; } static FilterChainMatch fromEnvoyProtoFilterChainMatch( @@ -274,13 +280,19 @@ public final class EnvoyServerProtoData { default: throw new InvalidProtocolBufferException("Unknown source-type:" + proto.getSourceType()); } + List serverNames = new ArrayList<>(); + for (String serverName : proto.getServerNamesList()) { + serverNames.add(serverName); + } return new FilterChainMatch( proto.getDestinationPort().getValue(), prefixRanges, applicationProtocols, sourcePrefixRanges, sourceType, - proto.getSourcePortsList()); + proto.getSourcePortsList(), + serverNames, + proto.getTransportProtocol()); } public int getDestinationPort() { @@ -307,6 +319,14 @@ public final class EnvoyServerProtoData { return sourcePorts; } + public List getServerNames() { + return serverNames; + } + + public String getTransportProtocol() { + return transportProtocol; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -321,7 +341,9 @@ public final class EnvoyServerProtoData { && Objects.equals(applicationProtocols, that.applicationProtocols) && Objects.equals(sourcePrefixRanges, that.sourcePrefixRanges) && sourceType == that.sourceType - && Objects.equals(sourcePorts, that.sourcePorts); + && Objects.equals(sourcePorts, that.sourcePorts) + && Objects.equals(serverNames, that.serverNames) + && Objects.equals(transportProtocol, that.transportProtocol); } @Override @@ -332,7 +354,9 @@ public final class EnvoyServerProtoData { applicationProtocols, sourcePrefixRanges, sourceType, - sourcePorts); + sourcePorts, + serverNames, + transportProtocol); } @Override @@ -344,6 +368,8 @@ public final class EnvoyServerProtoData { .add("sourcePrefixRanges", sourcePrefixRanges) .add("sourceType", sourceType) .add("sourcePorts", sourcePorts) + .add("serverNames", serverNames) + .add("transportProtocol", transportProtocol) .toString(); } } @@ -559,32 +585,12 @@ public final class EnvoyServerProtoData { List filterChains = new ArrayList<>(inputFilterChains.size()); for (io.envoyproxy.envoy.config.listener.v3.FilterChain filterChain : inputFilterChains) { - if (isAcceptable(filterChain.getFilterChainMatch())) { - filterChains - .add(FilterChain.fromEnvoyProtoFilterChain(filterChain, tlsContextManager, false)); - } + filterChains + .add(FilterChain.fromEnvoyProtoFilterChain(filterChain, tlsContextManager, false)); } return filterChains; } - // check if a filter is acceptable for gRPC server side processing - private static boolean isAcceptable( - io.envoyproxy.envoy.config.listener.v3.FilterChainMatch filterChainMatch) { - // reject if filer-chain-match - // - has server_name - // - transport protocol is other than "raw_buffer" - // - application_protocols is non-empty - if (!filterChainMatch.getServerNamesList().isEmpty()) { - return false; - } - String transportProtocol = filterChainMatch.getTransportProtocol(); - if (!transportProtocol.isEmpty() && !"raw_buffer".equals(transportProtocol)) { - return false; - } - List appProtocols = filterChainMatch.getApplicationProtocolsList(); - return appProtocols.isEmpty(); - } - public String getName() { return name; } diff --git a/xds/src/main/java/io/grpc/xds/XdsClientWrapperForServerSds.java b/xds/src/main/java/io/grpc/xds/XdsClientWrapperForServerSds.java index d2674d263b..08c1f2cf17 100644 --- a/xds/src/main/java/io/grpc/xds/XdsClientWrapperForServerSds.java +++ b/xds/src/main/java/io/grpc/xds/XdsClientWrapperForServerSds.java @@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Strings; import com.google.common.collect.ImmutableSet; import com.google.protobuf.UInt32Value; import io.grpc.Internal; @@ -223,6 +224,9 @@ public final class XdsClientWrapperForServerSds { filterChains = filterOnDestinationPort(filterChains); filterChains = filterOnIpAddress(filterChains, localInetAddr.getAddress(), true); + filterChains = filterOnServerNames(filterChains); + filterChains = filterOnTransportProtocol(filterChains); + filterChains = filterOnApplicationProtocols(filterChains); filterChains = filterOnSourceType(filterChains, remoteInetAddr.getAddress(), localInetAddr.getAddress()); filterChains = filterOnIpAddress(filterChains, remoteInetAddr.getAddress(), false); @@ -237,6 +241,46 @@ public final class XdsClientWrapperForServerSds { return listener.getDefaultFilterChain().getSslContextProviderSupplier(); } + // reject if filer-chain-match has non-empty application_protocols + private static List filterOnApplicationProtocols(List filterChains) { + ArrayList filtered = new ArrayList<>(filterChains.size()); + for (FilterChain filterChain : filterChains) { + FilterChainMatch filterChainMatch = filterChain.getFilterChainMatch(); + + if (filterChainMatch.getApplicationProtocols().isEmpty()) { + filtered.add(filterChain); + } + } + return filtered; + } + + // reject if filer-chain-match has non-empty transport protocol other than "raw_buffer" + private static List filterOnTransportProtocol(List filterChains) { + ArrayList filtered = new ArrayList<>(filterChains.size()); + for (FilterChain filterChain : filterChains) { + FilterChainMatch filterChainMatch = filterChain.getFilterChainMatch(); + + String transportProtocol = filterChainMatch.getTransportProtocol(); + if ( Strings.isNullOrEmpty(transportProtocol) || "raw_buffer".equals(transportProtocol)) { + filtered.add(filterChain); + } + } + return filtered; + } + + // reject if filer-chain-match has server_name(s) + private static List filterOnServerNames(List filterChains) { + ArrayList filtered = new ArrayList<>(filterChains.size()); + for (FilterChain filterChain : filterChains) { + FilterChainMatch filterChainMatch = filterChain.getFilterChainMatch(); + + if (filterChainMatch.getServerNames().isEmpty()) { + filtered.add(filterChain); + } + } + return filtered; + } + // destination_port present => Always fail match private static List filterOnDestinationPort(List filterChains) { ArrayList filtered = new ArrayList<>(filterChains.size()); diff --git a/xds/src/test/java/io/grpc/xds/EnvoyServerProtoDataTest.java b/xds/src/test/java/io/grpc/xds/EnvoyServerProtoDataTest.java index 00dfa50061..5e641e8a65 100644 --- a/xds/src/test/java/io/grpc/xds/EnvoyServerProtoDataTest.java +++ b/xds/src/test/java/io/grpc/xds/EnvoyServerProtoDataTest.java @@ -36,6 +36,7 @@ import io.grpc.xds.EnvoyServerProtoData.DownstreamTlsContext; import io.grpc.xds.EnvoyServerProtoData.Listener; import io.grpc.xds.internal.sds.CommonTlsContextTestsUtil; import io.grpc.xds.internal.sds.SslContextProviderSupplier; +import java.util.Arrays; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; @@ -75,7 +76,11 @@ public class EnvoyServerProtoDataTest { EnvoyServerProtoData.FilterChainMatch inFilterChainMatch = inFilter.getFilterChainMatch(); assertThat(inFilterChainMatch).isNotNull(); assertThat(inFilterChainMatch.getDestinationPort()).isEqualTo(8000); - assertThat(inFilterChainMatch.getApplicationProtocols()).isEmpty(); + assertThat(inFilterChainMatch.getApplicationProtocols()) + .containsExactlyElementsIn(Arrays.asList("managed-mtls", "h2")); + assertThat(inFilterChainMatch.getServerNames()) + .containsExactlyElementsIn(Arrays.asList("server1", "server2")); + assertThat(inFilterChainMatch.getTransportProtocol()).isEqualTo("tls"); assertThat(inFilterChainMatch.getPrefixRanges()) .containsExactly(new EnvoyServerProtoData.CidrRange("10.20.0.15", 32)); assertThat(inFilterChainMatch.getSourcePrefixRanges()) @@ -111,6 +116,9 @@ public class EnvoyServerProtoDataTest { .setFilterChainMatch( FilterChainMatch.newBuilder() .setDestinationPort(UInt32Value.of(8000)) + .addAllServerNames(Arrays.asList("server1", "server2")) + .setTransportProtocol("tls") + .addAllApplicationProtocols(Arrays.asList("managed-mtls", "h2")) .addPrefixRanges(CidrRange.newBuilder() .setAddressPrefix("10.20.0.15") .setPrefixLen(UInt32Value.of(32)) diff --git a/xds/src/test/java/io/grpc/xds/FilterChainMatchTest.java b/xds/src/test/java/io/grpc/xds/FilterChainMatchTest.java index 36152c342a..dfe80cd339 100644 --- a/xds/src/test/java/io/grpc/xds/FilterChainMatchTest.java +++ b/xds/src/test/java/io/grpc/xds/FilterChainMatchTest.java @@ -18,9 +18,20 @@ package io.grpc.xds; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import com.google.protobuf.Any; import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.UInt32Value; +import io.envoyproxy.envoy.config.core.v3.Address; +import io.envoyproxy.envoy.config.core.v3.CidrRange; +import io.envoyproxy.envoy.config.core.v3.SocketAddress; +import io.envoyproxy.envoy.config.core.v3.TrafficDirection; +import io.envoyproxy.envoy.config.core.v3.TransportSocket; +import io.envoyproxy.envoy.config.listener.v3.Filter; +import io.envoyproxy.envoy.config.listener.v3.FilterChain; +import io.envoyproxy.envoy.config.listener.v3.FilterChainMatch; import io.grpc.xds.EnvoyServerProtoData.DownstreamTlsContext; import io.grpc.xds.internal.sds.CommonTlsContextTestsUtil; import io.grpc.xds.internal.sds.SslContextProviderSupplier; @@ -87,7 +98,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); DownstreamTlsContext tlsContext = CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"); EnvoyServerProtoData.FilterChain filterChain = @@ -110,17 +123,24 @@ public class FilterChainMatchTest { Arrays.asList("managed-mtls"), Arrays.asList(), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); DownstreamTlsContext tlsContext = CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"); EnvoyServerProtoData.FilterChain filterChain = new EnvoyServerProtoData.FilterChain(filterChainMatch, tlsContext, tlsContextManager); + DownstreamTlsContext defaultTlsContext = + CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT2", "VA2"); + EnvoyServerProtoData.FilterChain defaultFilterChain = + new EnvoyServerProtoData.FilterChain(null, defaultTlsContext, tlsContextManager); EnvoyServerProtoData.Listener listener = - new EnvoyServerProtoData.Listener("listener1", LOCAL_IP, Arrays.asList(filterChain), null); + new EnvoyServerProtoData.Listener("listener1", LOCAL_IP, Arrays.asList(filterChain), + defaultFilterChain); XdsClient.LdsUpdate listenerUpdate = new XdsClient.LdsUpdate(listener); registeredWatcher.onChanged(listenerUpdate); DownstreamTlsContext tlsContext1 = getDownstreamTlsContext(); - assertThat(tlsContext1).isSameInstanceAs(tlsContext); + assertThat(tlsContext1).isSameInstanceAs(defaultTlsContext); } @Test @@ -151,7 +171,9 @@ public class FilterChainMatchTest { Arrays.asList("managed-mtls"), Arrays.asList(), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChainWithDestPort = new EnvoyServerProtoData.FilterChain(filterChainMatchWithDestPort, tlsContextWithDestPort, tlsContextManager); @@ -181,7 +203,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChainWithMatch = new EnvoyServerProtoData.FilterChain(filterChainMatchWithMatch, tlsContextMatch, tlsContextManager); @@ -213,7 +237,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChainWithMismatch = new EnvoyServerProtoData.FilterChain(filterChainMatchWithMismatch, tlsContextMismatch, tlsContextManager); @@ -245,7 +271,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChain0Length = new EnvoyServerProtoData.FilterChain(filterChainMatch0Length, tlsContext0Length, tlsContextManager); @@ -276,7 +304,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChainLessSpecific = new EnvoyServerProtoData.FilterChain(filterChainMatchLessSpecific, tlsContextLessSpecific, tlsContextManager); @@ -290,7 +320,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChainMoreSpecific = new EnvoyServerProtoData.FilterChain(filterChainMatchMoreSpecific, tlsContextMoreSpecific, tlsContextManager); @@ -321,7 +353,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChainLessSpecific = new EnvoyServerProtoData.FilterChain(filterChainMatchLessSpecific, tlsContextLessSpecific, tlsContextManager); @@ -335,7 +369,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChainMoreSpecific = new EnvoyServerProtoData.FilterChain(filterChainMatchMoreSpecific, tlsContextMoreSpecific, tlsContextManager); @@ -366,7 +402,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChainLessSpecific = new EnvoyServerProtoData.FilterChain(filterChainMatchLessSpecific, tlsContextLessSpecific, tlsContextManager); @@ -380,7 +418,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChainMoreSpecific = new EnvoyServerProtoData.FilterChain(filterChainMatchMoreSpecific, tlsContextMoreSpecific, tlsContextManager); @@ -413,7 +453,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChainMoreSpecificWith2 = new EnvoyServerProtoData.FilterChain( filterChainMatchMoreSpecificWith2, tlsContextMoreSpecificWith2, tlsContextManager); @@ -427,7 +469,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChainLessSpecific = new EnvoyServerProtoData.FilterChain(filterChainMatchLessSpecific, tlsContextLessSpecific, tlsContextManager); @@ -457,7 +501,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(), EnvoyServerProtoData.ConnectionSourceType.SAME_IP_OR_LOOPBACK, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChainWithMismatch = new EnvoyServerProtoData.FilterChain(filterChainMatchWithMismatch, tlsContextMismatch, tlsContextManager); @@ -487,7 +533,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(), EnvoyServerProtoData.ConnectionSourceType.SAME_IP_OR_LOOPBACK, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChainWithMatch = new EnvoyServerProtoData.FilterChain(filterChainMatchWithMatch, tlsContextMatch, tlsContextManager); @@ -520,7 +568,9 @@ public class FilterChainMatchTest { new EnvoyServerProtoData.CidrRange("10.4.2.0", 24), new EnvoyServerProtoData.CidrRange(REMOTE_IP, 32)), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChainMoreSpecificWith2 = new EnvoyServerProtoData.FilterChain( filterChainMatchMoreSpecificWith2, tlsContextMoreSpecificWith2, tlsContextManager); @@ -534,7 +584,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(new EnvoyServerProtoData.CidrRange("10.4.2.2", 31)), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChainLessSpecific = new EnvoyServerProtoData.FilterChain(filterChainMatchLessSpecific, tlsContextLessSpecific, tlsContextManager); @@ -567,7 +619,9 @@ public class FilterChainMatchTest { new EnvoyServerProtoData.CidrRange("10.4.2.0", 24), new EnvoyServerProtoData.CidrRange("192.168.10.2", 32)), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChain1 = new EnvoyServerProtoData.FilterChain(filterChainMatch1, tlsContext1, tlsContextManager); @@ -580,7 +634,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(new EnvoyServerProtoData.CidrRange("10.4.2.0", 24)), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChain2 = new EnvoyServerProtoData.FilterChain(filterChainMatch2, tlsContext2, tlsContextManager); EnvoyServerProtoData.FilterChain defaultFilterChain = @@ -613,7 +669,9 @@ public class FilterChainMatchTest { new EnvoyServerProtoData.CidrRange("10.4.2.0", 24), new EnvoyServerProtoData.CidrRange("10.4.2.2", 31)), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChainEmptySourcePorts = new EnvoyServerProtoData.FilterChain( filterChainMatchEmptySourcePorts, tlsContextEmptySourcePorts, tlsContextManager); @@ -627,7 +685,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(new EnvoyServerProtoData.CidrRange("10.4.2.2", 31)), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList(7000, 15000)); + Arrays.asList(7000, 15000), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChainSourcePortMatch = new EnvoyServerProtoData.FilterChain( filterChainMatchSourcePortMatch, tlsContextSourcePortMatch, tlsContextManager); @@ -676,7 +736,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(new EnvoyServerProtoData.CidrRange(REMOTE_IP, 32)), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChain1 = new EnvoyServerProtoData.FilterChain(filterChainMatch1, tlsContext1, tlsContextManager); @@ -690,7 +752,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(new EnvoyServerProtoData.CidrRange("10.4.0.0", 16)), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChain2 = new EnvoyServerProtoData.FilterChain(filterChainMatch2, tlsContext2, tlsContextManager); @@ -704,7 +768,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(), EnvoyServerProtoData.ConnectionSourceType.SAME_IP_OR_LOOPBACK, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChain3 = new EnvoyServerProtoData.FilterChain(filterChainMatch3, tlsContext3, tlsContextManager); @@ -719,7 +785,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(new EnvoyServerProtoData.CidrRange("10.4.2.0", 24)), EnvoyServerProtoData.ConnectionSourceType.EXTERNAL, - Arrays.asList(16000, 9000)); + Arrays.asList(16000, 9000), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChain4 = new EnvoyServerProtoData.FilterChain(filterChainMatch4, tlsContext4, tlsContextManager); @@ -736,7 +804,9 @@ public class FilterChainMatchTest { new EnvoyServerProtoData.CidrRange("10.4.2.0", 24), new EnvoyServerProtoData.CidrRange("192.168.2.0", 24)), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList(15000, 8000)); + Arrays.asList(15000, 8000), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChain5 = new EnvoyServerProtoData.FilterChain(filterChainMatch5, tlsContext5, tlsContextManager); @@ -748,7 +818,9 @@ public class FilterChainMatchTest { Arrays.asList(), Arrays.asList(), EnvoyServerProtoData.ConnectionSourceType.ANY, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChain6 = new EnvoyServerProtoData.FilterChain(filterChainMatch6, tlsContext6, tlsContextManager); @@ -767,6 +839,108 @@ public class FilterChainMatchTest { assertThat(tlsContextPicked).isSameInstanceAs(tlsContext5); } + @Test + public void filterChainMatch_unsupportedMatchers() + throws InvalidProtocolBufferException, UnknownHostException { + setupChannel(LOCAL_IP, REMOTE_IP, 15000); + io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext tlsContext1 = + CommonTlsContextTestsUtil.buildTestDownstreamTlsContext( + "CERT1", "ROOTCA"); + io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext tlsContext2 = + CommonTlsContextTestsUtil.buildTestDownstreamTlsContext( + "CERT2", "ROOTCA"); + io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext tlsContext3 = + CommonTlsContextTestsUtil.buildTestDownstreamTlsContext( + "CERT3", "ROOTCA"); + + FilterChainMatch filterChainMatch1 = + FilterChainMatch.newBuilder() + .addAllServerNames(Arrays.asList("server1", "server2")) + .setTransportProtocol("tls") + .addAllApplicationProtocols(Arrays.asList("managed-mtls", "h2")) + .addPrefixRanges(CidrRange.newBuilder() + .setAddressPrefix("10.1.0.0") + .setPrefixLen(UInt32Value.of(16)) + .build()) + .build(); + + FilterChainMatch filterChainMatch2 = + FilterChainMatch.newBuilder() + .addPrefixRanges(CidrRange.newBuilder() + .setAddressPrefix("10.0.0.0") + .setPrefixLen(UInt32Value.of(8)) + .build()) + .build(); + + FilterChain filterChain1 = + FilterChain.newBuilder() + .setFilterChainMatch(filterChainMatch1) + .setTransportSocket(TransportSocket.newBuilder().setName("envoy.transport_sockets.tls") + .setTypedConfig(Any.pack(tlsContext1)) + .build()) + .addFilters(Filter.newBuilder() + .setName("envoy.http_connection_manager") + .setTypedConfig(Any.newBuilder() + .setTypeUrl( + "type.googleapis.com/" + + "envoy.extensions.filters.network.http_connection_manager" + + ".v3.HttpConnectionManager")) + .build()) + .build(); + FilterChain filterChain2 = + FilterChain.newBuilder() + .setFilterChainMatch(filterChainMatch2) + .setTransportSocket(TransportSocket.newBuilder().setName("envoy.transport_sockets.tls") + .setTypedConfig(Any.pack(tlsContext2)) + .build()) + .addFilters(Filter.newBuilder() + .setName("envoy.http_connection_manager") + .setTypedConfig(Any.newBuilder() + .setTypeUrl( + "type.googleapis.com/" + + "envoy.extensions.filters.network.http_connection_manager" + + ".v3.HttpConnectionManager")) + .build()) + .build(); + FilterChain defaultFilterChain = + FilterChain.newBuilder() + .setTransportSocket(TransportSocket.newBuilder().setName("envoy.transport_sockets.tls") + .setTypedConfig(Any.pack(tlsContext3)) + .build()) + .addFilters(Filter.newBuilder() + .setName("envoy.http_connection_manager") + .setTypedConfig(Any.newBuilder() + .setTypeUrl( + "type.googleapis.com/" + + "envoy.extensions.filters.network.http_connection_manager" + + ".v3.HttpConnectionManager")) + .build()) + .build(); + Address address = + Address.newBuilder() + .setSocketAddress( + SocketAddress.newBuilder().setPortValue(8000).setAddress("10.2.1.34").build()) + .build(); + io.envoyproxy.envoy.config.listener.v3.Listener listener = + io.envoyproxy.envoy.config.listener.v3.Listener.newBuilder() + .setName("8000") + .setAddress(address) + .addFilterChains(filterChain1) + .addFilterChains(filterChain2) + .setDefaultFilterChain(defaultFilterChain) + .setTrafficDirection(TrafficDirection.INBOUND) + .build(); + + EnvoyServerProtoData.Listener xdsListener = EnvoyServerProtoData.Listener + .fromEnvoyProtoListener(listener, mock(TlsContextManager.class)); + XdsClient.LdsUpdate listenerUpdate = new XdsClient.LdsUpdate(xdsListener); + registeredWatcher.onChanged(listenerUpdate); + DownstreamTlsContext tlsContextPicked = getDownstreamTlsContext(); + // assert defaultFilterChain match + assertThat(tlsContextPicked.getCommonTlsContext().getTlsCertificateSdsSecretConfigsList().get(0) + .getName()).isEqualTo("CERT3"); + } + private void setupChannel(String localIp, String remoteIp, int remotePort) throws UnknownHostException { when(channel.localAddress()) diff --git a/xds/src/test/java/io/grpc/xds/XdsSdsClientServerTest.java b/xds/src/test/java/io/grpc/xds/XdsSdsClientServerTest.java index efa59b69c0..c5799aad5b 100644 --- a/xds/src/test/java/io/grpc/xds/XdsSdsClientServerTest.java +++ b/xds/src/test/java/io/grpc/xds/XdsSdsClientServerTest.java @@ -374,7 +374,9 @@ public class XdsSdsClientServerTest { Arrays.asList(), Arrays.asList(), null, - Arrays.asList()); + Arrays.asList(), + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain defaultFilterChain = new EnvoyServerProtoData.FilterChain(filterChainMatch, tlsContext, tlsContextManager); EnvoyServerProtoData.Listener listener = diff --git a/xds/src/test/java/io/grpc/xds/XdsServerTestHelper.java b/xds/src/test/java/io/grpc/xds/XdsServerTestHelper.java index ef74584fb1..a960818059 100644 --- a/xds/src/test/java/io/grpc/xds/XdsServerTestHelper.java +++ b/xds/src/test/java/io/grpc/xds/XdsServerTestHelper.java @@ -155,7 +155,9 @@ class XdsServerTestHelper { Arrays.asList(), Arrays.asList(), null, - sourcePorts); + sourcePorts, + Arrays.asList(), + null); EnvoyServerProtoData.FilterChain filterChain1 = new EnvoyServerProtoData.FilterChain(filterChainMatch1, tlsContext, tlsContextManager); EnvoyServerProtoData.FilterChain defaultFilterChain =