| /* |
| * Copyright 2021 The gRPC Authors |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package io.grpc.xds; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| import static org.junit.Assert.fail; |
| import static org.mockito.Mockito.when; |
| |
| import com.google.protobuf.InvalidProtocolBufferException; |
| import io.grpc.xds.EnvoyServerProtoData.DownstreamTlsContext; |
| import io.grpc.xds.internal.sds.CommonTlsContextTestsUtil; |
| import io.netty.channel.Channel; |
| import java.io.IOException; |
| import java.net.InetAddress; |
| import java.net.InetSocketAddress; |
| import java.net.UnknownHostException; |
| import java.util.Arrays; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.JUnit4; |
| import org.mockito.Mock; |
| import org.mockito.MockitoAnnotations; |
| |
| /** Tests for {@link XdsClientWrapperForServerSds}. */ |
| @RunWith(JUnit4.class) |
| public class FilterChainMatchTest { |
| |
| private static final int PORT = 7000; |
| private static final String LOCAL_IP = "10.1.2.3"; // dest |
| private static final String REMOTE_IP = "10.4.2.3"; // source |
| |
| @Mock private XdsClient xdsClient; |
| @Mock private Channel channel; |
| |
| private XdsClientWrapperForServerSds xdsClientWrapperForServerSds; |
| private XdsClient.LdsResourceWatcher registeredWatcher; |
| |
| @Before |
| public void setUp() throws IOException { |
| MockitoAnnotations.initMocks(this); |
| xdsClientWrapperForServerSds = new XdsClientWrapperForServerSds(PORT); |
| registeredWatcher = |
| XdsServerTestHelper.startAndGetWatcher(xdsClientWrapperForServerSds, xdsClient, PORT); |
| } |
| |
| @After |
| public void tearDown() { |
| xdsClientWrapperForServerSds.shutdown(); |
| } |
| |
| @Test |
| public void singleFilterChainWithoutAlpn() throws UnknownHostException { |
| setupChannel(LOCAL_IP, REMOTE_IP, 15000); |
| EnvoyServerProtoData.FilterChainMatch filterChainMatch = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| Arrays.<String>asList(), |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| DownstreamTlsContext tlsContext = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"); |
| EnvoyServerProtoData.FilterChain filterChain = |
| new EnvoyServerProtoData.FilterChain(filterChainMatch, tlsContext); |
| EnvoyServerProtoData.Listener listener = |
| new EnvoyServerProtoData.Listener("listener1", LOCAL_IP, Arrays.asList(filterChain), null); |
| XdsClient.LdsUpdate listenerUpdate = new XdsClient.LdsUpdate(listener); |
| registeredWatcher.onChanged(listenerUpdate); |
| DownstreamTlsContext tlsContext1 = |
| xdsClientWrapperForServerSds.getDownstreamTlsContext(channel); |
| assertThat(tlsContext1).isSameInstanceAs(tlsContext); |
| } |
| |
| @Test |
| public void singleFilterChainWithAlpn() throws UnknownHostException { |
| setupChannel(LOCAL_IP, REMOTE_IP, 15000); |
| EnvoyServerProtoData.FilterChainMatch filterChainMatch = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| Arrays.asList("managed-mtls"), |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| DownstreamTlsContext tlsContext = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"); |
| EnvoyServerProtoData.FilterChain filterChain = |
| new EnvoyServerProtoData.FilterChain(filterChainMatch, tlsContext); |
| EnvoyServerProtoData.Listener listener = |
| new EnvoyServerProtoData.Listener("listener1", LOCAL_IP, Arrays.asList(filterChain), null); |
| XdsClient.LdsUpdate listenerUpdate = new XdsClient.LdsUpdate(listener); |
| registeredWatcher.onChanged(listenerUpdate); |
| DownstreamTlsContext tlsContext1 = |
| xdsClientWrapperForServerSds.getDownstreamTlsContext(channel); |
| assertThat(tlsContext1).isSameInstanceAs(tlsContext); |
| } |
| |
| @Test |
| public void defaultFilterChain() throws UnknownHostException { |
| setupChannel(LOCAL_IP, REMOTE_IP, 15000); |
| DownstreamTlsContext tlsContext = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"); |
| EnvoyServerProtoData.FilterChain filterChain = |
| new EnvoyServerProtoData.FilterChain(null, tlsContext); |
| EnvoyServerProtoData.Listener listener = |
| new EnvoyServerProtoData.Listener( |
| "listener1", LOCAL_IP, Arrays.<EnvoyServerProtoData.FilterChain>asList(), filterChain); |
| XdsClient.LdsUpdate listenerUpdate = new XdsClient.LdsUpdate(listener); |
| registeredWatcher.onChanged(listenerUpdate); |
| DownstreamTlsContext tlsContext1 = |
| xdsClientWrapperForServerSds.getDownstreamTlsContext(channel); |
| assertThat(tlsContext1).isSameInstanceAs(tlsContext); |
| } |
| |
| @Test |
| public void destPortFails_returnDefaultFilterChain() throws UnknownHostException { |
| setupChannel(LOCAL_IP, REMOTE_IP, 15000); |
| DownstreamTlsContext tlsContextWithDestPort = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"); |
| EnvoyServerProtoData.FilterChainMatch filterChainMatchWithDestPort = |
| new EnvoyServerProtoData.FilterChainMatch( |
| PORT, |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| Arrays.asList("managed-mtls"), |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChainWithDestPort = |
| new EnvoyServerProtoData.FilterChain(filterChainMatchWithDestPort, tlsContextWithDestPort); |
| DownstreamTlsContext tlsContextForDefaultFilterChain = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT2", "VA2"); |
| EnvoyServerProtoData.FilterChain defaultFilterChain = |
| new EnvoyServerProtoData.FilterChain(null, tlsContextForDefaultFilterChain); |
| EnvoyServerProtoData.Listener listener = |
| new EnvoyServerProtoData.Listener( |
| "listener1", LOCAL_IP, Arrays.asList(filterChainWithDestPort), defaultFilterChain); |
| XdsClient.LdsUpdate listenerUpdate = new XdsClient.LdsUpdate(listener); |
| registeredWatcher.onChanged(listenerUpdate); |
| DownstreamTlsContext tlsContext1 = |
| xdsClientWrapperForServerSds.getDownstreamTlsContext(channel); |
| assertThat(tlsContext1).isSameInstanceAs(tlsContextForDefaultFilterChain); |
| } |
| |
| @Test |
| public void destPrefixRangeMatch() throws UnknownHostException, InvalidProtocolBufferException { |
| setupChannel(LOCAL_IP, REMOTE_IP, 15000); |
| DownstreamTlsContext tlsContextMatch = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"); |
| EnvoyServerProtoData.FilterChainMatch filterChainMatchWithMatch = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.asList(new EnvoyServerProtoData.CidrRange("10.1.2.0", 24)), |
| Arrays.<String>asList(), |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChainWithMatch = |
| new EnvoyServerProtoData.FilterChain(filterChainMatchWithMatch, tlsContextMatch); |
| DownstreamTlsContext tlsContextForDefaultFilterChain = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT2", "VA2"); |
| EnvoyServerProtoData.FilterChain defaultFilterChain = |
| new EnvoyServerProtoData.FilterChain(null, tlsContextForDefaultFilterChain); |
| EnvoyServerProtoData.Listener listener = |
| new EnvoyServerProtoData.Listener( |
| "listener1", LOCAL_IP, Arrays.asList(filterChainWithMatch), defaultFilterChain); |
| XdsClient.LdsUpdate listenerUpdate = new XdsClient.LdsUpdate(listener); |
| registeredWatcher.onChanged(listenerUpdate); |
| DownstreamTlsContext tlsContext1 = |
| xdsClientWrapperForServerSds.getDownstreamTlsContext(channel); |
| assertThat(tlsContext1).isSameInstanceAs(tlsContextMatch); |
| } |
| |
| @Test |
| public void destPrefixRangeMismatch_returnDefaultFilterChain() |
| throws UnknownHostException, InvalidProtocolBufferException { |
| setupChannel(LOCAL_IP, REMOTE_IP, 15000); |
| DownstreamTlsContext tlsContextMismatch = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"); |
| // 10.2.2.0/24 doesn't match LOCAL_IP |
| EnvoyServerProtoData.FilterChainMatch filterChainMatchWithMismatch = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.asList(new EnvoyServerProtoData.CidrRange("10.2.2.0", 24)), |
| Arrays.<String>asList(), |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChainWithMismatch = |
| new EnvoyServerProtoData.FilterChain(filterChainMatchWithMismatch, tlsContextMismatch); |
| DownstreamTlsContext tlsContextForDefaultFilterChain = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT2", "VA2"); |
| EnvoyServerProtoData.FilterChain defaultFilterChain = |
| new EnvoyServerProtoData.FilterChain(null, tlsContextForDefaultFilterChain); |
| EnvoyServerProtoData.Listener listener = |
| new EnvoyServerProtoData.Listener( |
| "listener1", LOCAL_IP, Arrays.asList(filterChainWithMismatch), defaultFilterChain); |
| XdsClient.LdsUpdate listenerUpdate = new XdsClient.LdsUpdate(listener); |
| registeredWatcher.onChanged(listenerUpdate); |
| DownstreamTlsContext tlsContext1 = |
| xdsClientWrapperForServerSds.getDownstreamTlsContext(channel); |
| assertThat(tlsContext1).isSameInstanceAs(tlsContextForDefaultFilterChain); |
| } |
| |
| @Test |
| public void dest0LengthPrefixRange() |
| throws UnknownHostException, InvalidProtocolBufferException { |
| setupChannel(LOCAL_IP, REMOTE_IP, 15000); |
| DownstreamTlsContext tlsContext0Length = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"); |
| // 10.2.2.0/24 doesn't match LOCAL_IP |
| EnvoyServerProtoData.FilterChainMatch filterChainMatch0Length = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.asList(new EnvoyServerProtoData.CidrRange("10.2.2.0", 0)), |
| Arrays.<String>asList(), |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChain0Length = |
| new EnvoyServerProtoData.FilterChain(filterChainMatch0Length, tlsContext0Length); |
| DownstreamTlsContext tlsContextForDefaultFilterChain = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT2", "VA2"); |
| EnvoyServerProtoData.FilterChain defaultFilterChain = |
| new EnvoyServerProtoData.FilterChain(null, tlsContextForDefaultFilterChain); |
| EnvoyServerProtoData.Listener listener = |
| new EnvoyServerProtoData.Listener( |
| "listener1", LOCAL_IP, Arrays.asList(filterChain0Length), defaultFilterChain); |
| XdsClient.LdsUpdate listenerUpdate = new XdsClient.LdsUpdate(listener); |
| registeredWatcher.onChanged(listenerUpdate); |
| DownstreamTlsContext tlsContext1 = |
| xdsClientWrapperForServerSds.getDownstreamTlsContext(channel); |
| assertThat(tlsContext1).isSameInstanceAs(tlsContext0Length); |
| } |
| |
| @Test |
| public void destPrefixRange_moreSpecificWins() |
| throws UnknownHostException, InvalidProtocolBufferException { |
| setupChannel(LOCAL_IP, REMOTE_IP, 15000); |
| DownstreamTlsContext tlsContextLessSpecific = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"); |
| EnvoyServerProtoData.FilterChainMatch filterChainMatchLessSpecific = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.asList(new EnvoyServerProtoData.CidrRange("10.1.2.0", 24)), |
| Arrays.<String>asList(), |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChainLessSpecific = |
| new EnvoyServerProtoData.FilterChain(filterChainMatchLessSpecific, tlsContextLessSpecific); |
| |
| DownstreamTlsContext tlsContextMoreSpecific = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT2", "VA2"); |
| EnvoyServerProtoData.FilterChainMatch filterChainMatchMoreSpecific = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.asList(new EnvoyServerProtoData.CidrRange("10.1.2.2", 31)), |
| Arrays.<String>asList(), |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChainMoreSpecific = |
| new EnvoyServerProtoData.FilterChain(filterChainMatchMoreSpecific, tlsContextMoreSpecific); |
| EnvoyServerProtoData.FilterChain defaultFilterChain = |
| new EnvoyServerProtoData.FilterChain(null, null); |
| EnvoyServerProtoData.Listener listener = |
| new EnvoyServerProtoData.Listener( |
| "listener1", |
| LOCAL_IP, |
| Arrays.asList(filterChainLessSpecific, filterChainMoreSpecific), |
| defaultFilterChain); |
| XdsClient.LdsUpdate listenerUpdate = new XdsClient.LdsUpdate(listener); |
| registeredWatcher.onChanged(listenerUpdate); |
| DownstreamTlsContext tlsContext1 = |
| xdsClientWrapperForServerSds.getDownstreamTlsContext(channel); |
| assertThat(tlsContext1).isSameInstanceAs(tlsContextMoreSpecific); |
| } |
| |
| @Test |
| public void destPrefixRange_emptyListLessSpecific() |
| throws UnknownHostException, InvalidProtocolBufferException { |
| setupChannel(LOCAL_IP, REMOTE_IP, 15000); |
| DownstreamTlsContext tlsContextLessSpecific = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"); |
| EnvoyServerProtoData.FilterChainMatch filterChainMatchLessSpecific = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| Arrays.<String>asList(), |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChainLessSpecific = |
| new EnvoyServerProtoData.FilterChain(filterChainMatchLessSpecific, tlsContextLessSpecific); |
| |
| DownstreamTlsContext tlsContextMoreSpecific = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT2", "VA2"); |
| EnvoyServerProtoData.FilterChainMatch filterChainMatchMoreSpecific = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.asList(new EnvoyServerProtoData.CidrRange("8.0.0.0", 5)), |
| Arrays.<String>asList(), |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChainMoreSpecific = |
| new EnvoyServerProtoData.FilterChain(filterChainMatchMoreSpecific, tlsContextMoreSpecific); |
| EnvoyServerProtoData.FilterChain defaultFilterChain = |
| new EnvoyServerProtoData.FilterChain(null, null); |
| EnvoyServerProtoData.Listener listener = |
| new EnvoyServerProtoData.Listener( |
| "listener1", |
| LOCAL_IP, |
| Arrays.asList(filterChainLessSpecific, filterChainMoreSpecific), |
| defaultFilterChain); |
| XdsClient.LdsUpdate listenerUpdate = new XdsClient.LdsUpdate(listener); |
| registeredWatcher.onChanged(listenerUpdate); |
| DownstreamTlsContext tlsContext1 = |
| xdsClientWrapperForServerSds.getDownstreamTlsContext(channel); |
| assertThat(tlsContext1).isSameInstanceAs(tlsContextMoreSpecific); |
| } |
| |
| @Test |
| public void destPrefixRangeIpv6_moreSpecificWins() |
| throws UnknownHostException, InvalidProtocolBufferException { |
| setupChannel("FE80:0000:0000:0000:0202:B3FF:FE1E:8329", "2001:DB8::8:800:200C:417A", 15000); |
| DownstreamTlsContext tlsContextLessSpecific = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"); |
| EnvoyServerProtoData.FilterChainMatch filterChainMatchLessSpecific = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.asList(new EnvoyServerProtoData.CidrRange("FE80:0:0:0:0:0:0:0", 60)), |
| Arrays.<String>asList(), |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChainLessSpecific = |
| new EnvoyServerProtoData.FilterChain(filterChainMatchLessSpecific, tlsContextLessSpecific); |
| |
| DownstreamTlsContext tlsContextMoreSpecific = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT2", "VA2"); |
| EnvoyServerProtoData.FilterChainMatch filterChainMatchMoreSpecific = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.asList(new EnvoyServerProtoData.CidrRange("FE80:0000:0000:0000:0202:0:0:0", 80)), |
| Arrays.<String>asList(), |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChainMoreSpecific = |
| new EnvoyServerProtoData.FilterChain(filterChainMatchMoreSpecific, tlsContextMoreSpecific); |
| EnvoyServerProtoData.FilterChain defaultFilterChain = |
| new EnvoyServerProtoData.FilterChain(null, null); |
| EnvoyServerProtoData.Listener listener = |
| new EnvoyServerProtoData.Listener( |
| "listener1", |
| "FE80:0000:0000:0000:0202:B3FF:FE1E:8329", |
| Arrays.asList(filterChainLessSpecific, filterChainMoreSpecific), |
| defaultFilterChain); |
| XdsClient.LdsUpdate listenerUpdate = new XdsClient.LdsUpdate(listener); |
| registeredWatcher.onChanged(listenerUpdate); |
| DownstreamTlsContext tlsContext1 = |
| xdsClientWrapperForServerSds.getDownstreamTlsContext(channel); |
| assertThat(tlsContext1).isSameInstanceAs(tlsContextMoreSpecific); |
| } |
| |
| @Test |
| public void destPrefixRange_moreSpecificWith2Wins() |
| throws UnknownHostException, InvalidProtocolBufferException { |
| setupChannel(LOCAL_IP, REMOTE_IP, 15000); |
| DownstreamTlsContext tlsContextMoreSpecificWith2 = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"); |
| EnvoyServerProtoData.FilterChainMatch filterChainMatchMoreSpecificWith2 = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.asList( |
| new EnvoyServerProtoData.CidrRange("10.1.2.0", 24), |
| new EnvoyServerProtoData.CidrRange(LOCAL_IP, 32)), |
| Arrays.<String>asList(), |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChainMoreSpecificWith2 = |
| new EnvoyServerProtoData.FilterChain( |
| filterChainMatchMoreSpecificWith2, tlsContextMoreSpecificWith2); |
| |
| DownstreamTlsContext tlsContextLessSpecific = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT2", "VA2"); |
| EnvoyServerProtoData.FilterChainMatch filterChainMatchLessSpecific = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.asList(new EnvoyServerProtoData.CidrRange("10.1.2.2", 31)), |
| Arrays.<String>asList(), |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChainLessSpecific = |
| new EnvoyServerProtoData.FilterChain(filterChainMatchLessSpecific, tlsContextLessSpecific); |
| EnvoyServerProtoData.FilterChain defaultFilterChain = |
| new EnvoyServerProtoData.FilterChain(null, null); |
| EnvoyServerProtoData.Listener listener = |
| new EnvoyServerProtoData.Listener( |
| "listener1", |
| LOCAL_IP, |
| Arrays.asList(filterChainMoreSpecificWith2, filterChainLessSpecific), |
| defaultFilterChain); |
| XdsClient.LdsUpdate listenerUpdate = new XdsClient.LdsUpdate(listener); |
| registeredWatcher.onChanged(listenerUpdate); |
| DownstreamTlsContext tlsContext1 = |
| xdsClientWrapperForServerSds.getDownstreamTlsContext(channel); |
| assertThat(tlsContext1).isSameInstanceAs(tlsContextMoreSpecificWith2); |
| } |
| |
| @Test |
| public void sourceTypeMismatch_returnDefaultFilterChain() throws UnknownHostException { |
| setupChannel(LOCAL_IP, REMOTE_IP, 15000); |
| DownstreamTlsContext tlsContextMismatch = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"); |
| EnvoyServerProtoData.FilterChainMatch filterChainMatchWithMismatch = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| Arrays.<String>asList(), |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| EnvoyServerProtoData.ConnectionSourceType.SAME_IP_OR_LOOPBACK, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChainWithMismatch = |
| new EnvoyServerProtoData.FilterChain(filterChainMatchWithMismatch, tlsContextMismatch); |
| DownstreamTlsContext tlsContextForDefaultFilterChain = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT2", "VA2"); |
| EnvoyServerProtoData.FilterChain defaultFilterChain = |
| new EnvoyServerProtoData.FilterChain(null, tlsContextForDefaultFilterChain); |
| EnvoyServerProtoData.Listener listener = |
| new EnvoyServerProtoData.Listener( |
| "listener1", LOCAL_IP, Arrays.asList(filterChainWithMismatch), defaultFilterChain); |
| XdsClient.LdsUpdate listenerUpdate = new XdsClient.LdsUpdate(listener); |
| registeredWatcher.onChanged(listenerUpdate); |
| DownstreamTlsContext tlsContext1 = |
| xdsClientWrapperForServerSds.getDownstreamTlsContext(channel); |
| assertThat(tlsContext1).isSameInstanceAs(tlsContextForDefaultFilterChain); |
| } |
| |
| @Test |
| public void sourceTypeLocal() throws UnknownHostException { |
| setupChannel(LOCAL_IP, LOCAL_IP, 15000); |
| DownstreamTlsContext tlsContextMatch = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"); |
| EnvoyServerProtoData.FilterChainMatch filterChainMatchWithMatch = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| Arrays.<String>asList(), |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| EnvoyServerProtoData.ConnectionSourceType.SAME_IP_OR_LOOPBACK, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChainWithMatch = |
| new EnvoyServerProtoData.FilterChain(filterChainMatchWithMatch, tlsContextMatch); |
| DownstreamTlsContext tlsContextForDefaultFilterChain = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT2", "VA2"); |
| EnvoyServerProtoData.FilterChain defaultFilterChain = |
| new EnvoyServerProtoData.FilterChain(null, tlsContextForDefaultFilterChain); |
| EnvoyServerProtoData.Listener listener = |
| new EnvoyServerProtoData.Listener( |
| "listener1", LOCAL_IP, Arrays.asList(filterChainWithMatch), defaultFilterChain); |
| XdsClient.LdsUpdate listenerUpdate = new XdsClient.LdsUpdate(listener); |
| registeredWatcher.onChanged(listenerUpdate); |
| DownstreamTlsContext tlsContext1 = |
| xdsClientWrapperForServerSds.getDownstreamTlsContext(channel); |
| assertThat(tlsContext1).isSameInstanceAs(tlsContextMatch); |
| } |
| |
| @Test |
| public void sourcePrefixRange_moreSpecificWith2Wins() |
| throws UnknownHostException, InvalidProtocolBufferException { |
| setupChannel(LOCAL_IP, REMOTE_IP, 15000); |
| DownstreamTlsContext tlsContextMoreSpecificWith2 = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"); |
| EnvoyServerProtoData.FilterChainMatch filterChainMatchMoreSpecificWith2 = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| Arrays.<String>asList(), |
| Arrays.asList( |
| new EnvoyServerProtoData.CidrRange("10.4.2.0", 24), |
| new EnvoyServerProtoData.CidrRange(REMOTE_IP, 32)), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChainMoreSpecificWith2 = |
| new EnvoyServerProtoData.FilterChain( |
| filterChainMatchMoreSpecificWith2, tlsContextMoreSpecificWith2); |
| |
| DownstreamTlsContext tlsContextLessSpecific = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT2", "VA2"); |
| EnvoyServerProtoData.FilterChainMatch filterChainMatchLessSpecific = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| Arrays.<String>asList(), |
| Arrays.asList(new EnvoyServerProtoData.CidrRange("10.4.2.2", 31)), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChainLessSpecific = |
| new EnvoyServerProtoData.FilterChain(filterChainMatchLessSpecific, tlsContextLessSpecific); |
| EnvoyServerProtoData.FilterChain defaultFilterChain = |
| new EnvoyServerProtoData.FilterChain(null, null); |
| EnvoyServerProtoData.Listener listener = |
| new EnvoyServerProtoData.Listener( |
| "listener1", |
| LOCAL_IP, |
| Arrays.asList(filterChainMoreSpecificWith2, filterChainLessSpecific), |
| defaultFilterChain); |
| XdsClient.LdsUpdate listenerUpdate = new XdsClient.LdsUpdate(listener); |
| registeredWatcher.onChanged(listenerUpdate); |
| DownstreamTlsContext tlsContext1 = |
| xdsClientWrapperForServerSds.getDownstreamTlsContext(channel); |
| assertThat(tlsContext1).isSameInstanceAs(tlsContextMoreSpecificWith2); |
| } |
| |
| @Test |
| public void sourcePrefixRange_2Matchers_expectException() |
| throws UnknownHostException, InvalidProtocolBufferException { |
| setupChannel(LOCAL_IP, REMOTE_IP, 15000); |
| DownstreamTlsContext tlsContext1 = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"); |
| EnvoyServerProtoData.FilterChainMatch filterChainMatch1 = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| Arrays.<String>asList(), |
| Arrays.asList( |
| new EnvoyServerProtoData.CidrRange("10.4.2.0", 24), |
| new EnvoyServerProtoData.CidrRange("192.168.10.2", 32)), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChain1 = |
| new EnvoyServerProtoData.FilterChain(filterChainMatch1, tlsContext1); |
| |
| DownstreamTlsContext tlsContext2 = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT2", "VA2"); |
| EnvoyServerProtoData.FilterChainMatch filterChainMatch2 = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| Arrays.<String>asList(), |
| Arrays.asList(new EnvoyServerProtoData.CidrRange("10.4.2.0", 24)), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChain2 = |
| new EnvoyServerProtoData.FilterChain(filterChainMatch2, tlsContext2); |
| EnvoyServerProtoData.FilterChain defaultFilterChain = |
| new EnvoyServerProtoData.FilterChain(null, null); |
| EnvoyServerProtoData.Listener listener = |
| new EnvoyServerProtoData.Listener( |
| "listener1", LOCAL_IP, Arrays.asList(filterChain1, filterChain2), defaultFilterChain); |
| XdsClient.LdsUpdate listenerUpdate = new XdsClient.LdsUpdate(listener); |
| registeredWatcher.onChanged(listenerUpdate); |
| try { |
| xdsClientWrapperForServerSds.getDownstreamTlsContext(channel); |
| fail("expect exception!"); |
| } catch (IllegalStateException ise) { |
| assertThat(ise).hasMessageThat().isEqualTo("Found 2 matching filter-chains"); |
| } |
| } |
| |
| @Test |
| public void sourcePortMatch_exactMatchWinsOverEmptyList() |
| throws UnknownHostException, InvalidProtocolBufferException { |
| setupChannel(LOCAL_IP, REMOTE_IP, 15000); |
| DownstreamTlsContext tlsContextEmptySourcePorts = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"); |
| EnvoyServerProtoData.FilterChainMatch filterChainMatchEmptySourcePorts = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| Arrays.<String>asList(), |
| Arrays.asList( |
| new EnvoyServerProtoData.CidrRange("10.4.2.0", 24), |
| new EnvoyServerProtoData.CidrRange("10.4.2.2", 31)), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChainEmptySourcePorts = |
| new EnvoyServerProtoData.FilterChain( |
| filterChainMatchEmptySourcePorts, tlsContextEmptySourcePorts); |
| |
| DownstreamTlsContext tlsContextSourcePortMatch = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT2", "VA2"); |
| EnvoyServerProtoData.FilterChainMatch filterChainMatchSourcePortMatch = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| Arrays.<String>asList(), |
| Arrays.asList(new EnvoyServerProtoData.CidrRange("10.4.2.2", 31)), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.asList(7000, 15000)); |
| EnvoyServerProtoData.FilterChain filterChainSourcePortMatch = |
| new EnvoyServerProtoData.FilterChain( |
| filterChainMatchSourcePortMatch, tlsContextSourcePortMatch); |
| EnvoyServerProtoData.FilterChain defaultFilterChain = |
| new EnvoyServerProtoData.FilterChain(null, null); |
| EnvoyServerProtoData.Listener listener = |
| new EnvoyServerProtoData.Listener( |
| "listener1", |
| LOCAL_IP, |
| Arrays.asList(filterChainEmptySourcePorts, filterChainSourcePortMatch), |
| defaultFilterChain); |
| XdsClient.LdsUpdate listenerUpdate = new XdsClient.LdsUpdate(listener); |
| registeredWatcher.onChanged(listenerUpdate); |
| DownstreamTlsContext tlsContext1 = |
| xdsClientWrapperForServerSds.getDownstreamTlsContext(channel); |
| assertThat(tlsContext1).isSameInstanceAs(tlsContextSourcePortMatch); |
| } |
| |
| /** |
| * Create 6 filterChains: - 1st filter chain has dest port & specific prefix range but is |
| * eliminated due to dest port - 5 advance to next step: 1 is eliminated due to being less |
| * specific than the remaining 4. - 4 advance to 3rd step: source type external eliminates one |
| * with local source_type. - 3 advance to 4th step: more specific 2 get picked based on |
| * source-prefix range. - 5th step: out of 2 one with matching source port gets picked |
| */ |
| @Test |
| public void filterChain_5stepMatch() throws UnknownHostException, InvalidProtocolBufferException { |
| setupChannel(LOCAL_IP, REMOTE_IP, 15000); |
| DownstreamTlsContext tlsContext1 = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"); |
| DownstreamTlsContext tlsContext2 = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT2", "VA2"); |
| DownstreamTlsContext tlsContext3 = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT3", "VA3"); |
| DownstreamTlsContext tlsContext4 = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT4", "VA4"); |
| DownstreamTlsContext tlsContext5 = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT5", "VA5"); |
| DownstreamTlsContext tlsContext6 = |
| CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT6", "VA6"); |
| |
| // has dest port and specific prefix ranges: gets eliminated in step 1 |
| EnvoyServerProtoData.FilterChainMatch filterChainMatch1 = |
| new EnvoyServerProtoData.FilterChainMatch( |
| PORT, |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| Arrays.<String>asList(), |
| Arrays.asList(new EnvoyServerProtoData.CidrRange(REMOTE_IP, 32)), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChain1 = |
| new EnvoyServerProtoData.FilterChain(filterChainMatch1, tlsContext1); |
| |
| // next 5 use prefix range: 4 with prefixLen of 30 and last one with 29 |
| |
| // has single prefix range: and less specific source prefix range: gets eliminated in step 4 |
| EnvoyServerProtoData.FilterChainMatch filterChainMatch2 = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.asList(new EnvoyServerProtoData.CidrRange("10.1.2.0", 30)), |
| Arrays.<String>asList(), |
| Arrays.asList(new EnvoyServerProtoData.CidrRange("10.4.0.0", 16)), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChain2 = |
| new EnvoyServerProtoData.FilterChain(filterChainMatch2, tlsContext2); |
| |
| // has prefix ranges with one not matching and source type local: gets eliminated in step 3 |
| EnvoyServerProtoData.FilterChainMatch filterChainMatch3 = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.asList( |
| new EnvoyServerProtoData.CidrRange("192.168.2.0", 24), |
| new EnvoyServerProtoData.CidrRange("10.1.2.0", 30)), |
| Arrays.<String>asList(), |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| EnvoyServerProtoData.ConnectionSourceType.SAME_IP_OR_LOOPBACK, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChain3 = |
| new EnvoyServerProtoData.FilterChain(filterChainMatch3, tlsContext3); |
| |
| // has prefix ranges with both matching and source type external but non matching source port: |
| // gets eliminated in step 5 |
| EnvoyServerProtoData.FilterChainMatch filterChainMatch4 = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.asList( |
| new EnvoyServerProtoData.CidrRange("10.1.0.0", 16), |
| new EnvoyServerProtoData.CidrRange("10.1.2.0", 30)), |
| Arrays.<String>asList(), |
| Arrays.asList(new EnvoyServerProtoData.CidrRange("10.4.2.0", 24)), |
| EnvoyServerProtoData.ConnectionSourceType.EXTERNAL, |
| Arrays.asList(16000, 9000)); |
| EnvoyServerProtoData.FilterChain filterChain4 = |
| new EnvoyServerProtoData.FilterChain(filterChainMatch4, tlsContext4); |
| |
| // has prefix ranges with both matching and source type external and matching source port: this |
| // gets selected |
| EnvoyServerProtoData.FilterChainMatch filterChainMatch5 = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.asList( |
| new EnvoyServerProtoData.CidrRange("10.1.0.0", 16), |
| new EnvoyServerProtoData.CidrRange("10.1.2.0", 30)), |
| Arrays.<String>asList(), |
| Arrays.asList( |
| new EnvoyServerProtoData.CidrRange("10.4.2.0", 24), |
| new EnvoyServerProtoData.CidrRange("192.168.2.0", 24)), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.asList(15000, 8000)); |
| EnvoyServerProtoData.FilterChain filterChain5 = |
| new EnvoyServerProtoData.FilterChain(filterChainMatch5, tlsContext5); |
| |
| // has prefix range with prefixLen of 29: gets eliminated in step 2 |
| EnvoyServerProtoData.FilterChainMatch filterChainMatch6 = |
| new EnvoyServerProtoData.FilterChainMatch( |
| 0, |
| Arrays.asList(new EnvoyServerProtoData.CidrRange("10.1.2.0", 29)), |
| Arrays.<String>asList(), |
| Arrays.<EnvoyServerProtoData.CidrRange>asList(), |
| EnvoyServerProtoData.ConnectionSourceType.ANY, |
| Arrays.<Integer>asList()); |
| EnvoyServerProtoData.FilterChain filterChain6 = |
| new EnvoyServerProtoData.FilterChain(filterChainMatch6, tlsContext6); |
| |
| EnvoyServerProtoData.FilterChain defaultFilterChain = |
| new EnvoyServerProtoData.FilterChain(null, null); |
| EnvoyServerProtoData.Listener listener = |
| new EnvoyServerProtoData.Listener( |
| "listener1", |
| LOCAL_IP, |
| Arrays.asList( |
| filterChain1, filterChain2, filterChain3, filterChain4, filterChain5, filterChain6), |
| defaultFilterChain); |
| XdsClient.LdsUpdate listenerUpdate = new XdsClient.LdsUpdate(listener); |
| registeredWatcher.onChanged(listenerUpdate); |
| DownstreamTlsContext tlsContextPicked = |
| xdsClientWrapperForServerSds.getDownstreamTlsContext(channel); |
| assertThat(tlsContextPicked).isSameInstanceAs(tlsContext5); |
| } |
| |
| private void setupChannel(String localIp, String remoteIp, int remotePort) |
| throws UnknownHostException { |
| when(channel.localAddress()) |
| .thenReturn(new InetSocketAddress(InetAddress.getByName(localIp), PORT)); |
| when(channel.remoteAddress()) |
| .thenReturn(new InetSocketAddress(InetAddress.getByName(remoteIp), remotePort)); |
| } |
| } |