mirror of https://github.com/grpc/grpc-java.git
xds: implement the new filterChainMatch algorithm (#7910)
This commit is contained in:
parent
a55e034732
commit
6a581f282b
|
|
@ -18,7 +18,7 @@ package io.grpc.xds;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static io.grpc.xds.EnvoyProtoData.TRANSPORT_SOCKET_NAME_TLS;
|
||||
import static io.grpc.xds.EnvoyServerProtoData.TRANSPORT_SOCKET_NAME_TLS;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.CaseFormat;
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ import javax.annotation.Nullable;
|
|||
*/
|
||||
// TODO(chengyuanzhang): put data types into smaller categories.
|
||||
final class EnvoyProtoData {
|
||||
static final String TRANSPORT_SOCKET_NAME_TLS = "envoy.transport_sockets.tls";
|
||||
|
||||
// Prevent instantiation.
|
||||
private EnvoyProtoData() {
|
||||
|
|
|
|||
|
|
@ -16,15 +16,16 @@
|
|||
|
||||
package io.grpc.xds;
|
||||
|
||||
import static io.grpc.xds.EnvoyProtoData.TRANSPORT_SOCKET_NAME_TLS;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.protobuf.Any;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import io.envoyproxy.envoy.config.core.v3.Address;
|
||||
import io.envoyproxy.envoy.config.core.v3.SocketAddress;
|
||||
import io.envoyproxy.envoy.extensions.transport_sockets.tls.v3.CommonTlsContext;
|
||||
import io.grpc.Internal;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
|
@ -38,6 +39,8 @@ import javax.annotation.Nullable;
|
|||
@Internal
|
||||
public final class EnvoyServerProtoData {
|
||||
|
||||
static final String TRANSPORT_SOCKET_NAME_TLS = "envoy.transport_sockets.tls";
|
||||
|
||||
// Prevent instantiation.
|
||||
private EnvoyServerProtoData() {
|
||||
}
|
||||
|
|
@ -144,21 +147,25 @@ public final class EnvoyServerProtoData {
|
|||
}
|
||||
|
||||
static final class CidrRange {
|
||||
private final String addressPrefix;
|
||||
private final InetAddress addressPrefix;
|
||||
private final int prefixLen;
|
||||
|
||||
@VisibleForTesting
|
||||
CidrRange(String addressPrefix, int prefixLen) {
|
||||
this.addressPrefix = addressPrefix;
|
||||
CidrRange(String addressPrefix, int prefixLen) throws InvalidProtocolBufferException {
|
||||
try {
|
||||
this.addressPrefix = InetAddress.getByName(addressPrefix);
|
||||
} catch (UnknownHostException e) {
|
||||
throw new InvalidProtocolBufferException(e.getMessage());
|
||||
}
|
||||
this.prefixLen = prefixLen;
|
||||
}
|
||||
|
||||
static CidrRange fromEnvoyProtoCidrRange(
|
||||
io.envoyproxy.envoy.config.core.v3.CidrRange proto) {
|
||||
io.envoyproxy.envoy.config.core.v3.CidrRange proto) throws InvalidProtocolBufferException {
|
||||
return new CidrRange(proto.getAddressPrefix(), proto.getPrefixLen().getValue());
|
||||
}
|
||||
|
||||
public String getAddressPrefix() {
|
||||
public InetAddress getAddressPrefix() {
|
||||
return addressPrefix;
|
||||
}
|
||||
|
||||
|
|
@ -193,6 +200,17 @@ public final class EnvoyServerProtoData {
|
|||
}
|
||||
}
|
||||
|
||||
enum ConnectionSourceType {
|
||||
// Any connection source matches.
|
||||
ANY,
|
||||
|
||||
// Match a connection originating from the same host.
|
||||
SAME_IP_OR_LOOPBACK,
|
||||
|
||||
// Match a connection originating from a different host.
|
||||
EXTERNAL
|
||||
}
|
||||
|
||||
/**
|
||||
* Corresponds to Envoy proto message
|
||||
* {@link io.envoyproxy.envoy.api.v2.listener.FilterChainMatch}.
|
||||
|
|
@ -201,29 +219,62 @@ public final class EnvoyServerProtoData {
|
|||
private final int destinationPort;
|
||||
private final List<CidrRange> prefixRanges;
|
||||
private final List<String> applicationProtocols;
|
||||
private final List<CidrRange> sourcePrefixRanges;
|
||||
private final ConnectionSourceType sourceType;
|
||||
private final List<Integer> sourcePorts;
|
||||
|
||||
@VisibleForTesting
|
||||
FilterChainMatch(int destinationPort,
|
||||
List<CidrRange> prefixRanges, List<String> applicationProtocols) {
|
||||
FilterChainMatch(
|
||||
int destinationPort,
|
||||
List<CidrRange> prefixRanges,
|
||||
List<String> applicationProtocols,
|
||||
List<CidrRange> sourcePrefixRanges,
|
||||
ConnectionSourceType sourceType,
|
||||
List<Integer> sourcePorts) {
|
||||
this.destinationPort = destinationPort;
|
||||
this.prefixRanges = Collections.unmodifiableList(prefixRanges);
|
||||
this.applicationProtocols = Collections.unmodifiableList(applicationProtocols);
|
||||
this.sourcePrefixRanges = sourcePrefixRanges;
|
||||
this.sourceType = sourceType;
|
||||
this.sourcePorts = sourcePorts;
|
||||
}
|
||||
|
||||
static FilterChainMatch fromEnvoyProtoFilterChainMatch(
|
||||
io.envoyproxy.envoy.config.listener.v3.FilterChainMatch proto) {
|
||||
io.envoyproxy.envoy.config.listener.v3.FilterChainMatch proto)
|
||||
throws InvalidProtocolBufferException {
|
||||
List<CidrRange> prefixRanges = new ArrayList<>();
|
||||
for (io.envoyproxy.envoy.config.core.v3.CidrRange range : proto.getPrefixRangesList()) {
|
||||
prefixRanges.add(CidrRange.fromEnvoyProtoCidrRange(range));
|
||||
}
|
||||
List<CidrRange> sourcePrefixRanges = new ArrayList<>();
|
||||
for (io.envoyproxy.envoy.config.core.v3.CidrRange range : proto.getSourcePrefixRangesList()) {
|
||||
sourcePrefixRanges.add(CidrRange.fromEnvoyProtoCidrRange(range));
|
||||
}
|
||||
List<String> applicationProtocols = new ArrayList<>();
|
||||
for (String appProtocol : proto.getApplicationProtocolsList()) {
|
||||
for (String appProtocol : proto.getApplicationProtocolsList()) {
|
||||
applicationProtocols.add(appProtocol);
|
||||
}
|
||||
ConnectionSourceType sourceType = null;
|
||||
switch (proto.getSourceType()) {
|
||||
case ANY:
|
||||
sourceType = ConnectionSourceType.ANY;
|
||||
break;
|
||||
case EXTERNAL:
|
||||
sourceType = ConnectionSourceType.EXTERNAL;
|
||||
break;
|
||||
case SAME_IP_OR_LOOPBACK:
|
||||
sourceType = ConnectionSourceType.SAME_IP_OR_LOOPBACK;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidProtocolBufferException("Unknown source-type:" + proto.getSourceType());
|
||||
}
|
||||
return new FilterChainMatch(
|
||||
proto.getDestinationPort().getValue(),
|
||||
prefixRanges,
|
||||
applicationProtocols);
|
||||
applicationProtocols,
|
||||
sourcePrefixRanges,
|
||||
sourceType,
|
||||
proto.getSourcePortsList());
|
||||
}
|
||||
|
||||
public int getDestinationPort() {
|
||||
|
|
@ -238,6 +289,18 @@ public final class EnvoyServerProtoData {
|
|||
return applicationProtocols;
|
||||
}
|
||||
|
||||
public List<CidrRange> getSourcePrefixRanges() {
|
||||
return sourcePrefixRanges;
|
||||
}
|
||||
|
||||
public ConnectionSourceType getConnectionSourceType() {
|
||||
return sourceType;
|
||||
}
|
||||
|
||||
public List<Integer> getSourcePorts() {
|
||||
return sourcePorts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
|
|
@ -248,22 +311,34 @@ public final class EnvoyServerProtoData {
|
|||
}
|
||||
FilterChainMatch that = (FilterChainMatch) o;
|
||||
return destinationPort == that.destinationPort
|
||||
&& java.util.Objects.equals(prefixRanges, that.prefixRanges)
|
||||
&& java.util.Objects.equals(applicationProtocols, that.applicationProtocols);
|
||||
&& Objects.equals(prefixRanges, that.prefixRanges)
|
||||
&& Objects.equals(applicationProtocols, that.applicationProtocols)
|
||||
&& Objects.equals(sourcePrefixRanges, that.sourcePrefixRanges)
|
||||
&& sourceType == that.sourceType
|
||||
&& Objects.equals(sourcePorts, that.sourcePorts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return java.util.Objects.hash(destinationPort, prefixRanges, applicationProtocols);
|
||||
return Objects.hash(
|
||||
destinationPort,
|
||||
prefixRanges,
|
||||
applicationProtocols,
|
||||
sourcePrefixRanges,
|
||||
sourceType,
|
||||
sourcePorts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FilterChainMatch{"
|
||||
+ "destinationPort=" + destinationPort
|
||||
+ ", prefixRanges=" + prefixRanges
|
||||
+ ", applicationProtocols=" + applicationProtocols
|
||||
+ '}';
|
||||
return MoreObjects.toStringHelper(this)
|
||||
.add("destinationPort", destinationPort)
|
||||
.add("prefixRanges", prefixRanges)
|
||||
.add("applicationProtocols", applicationProtocols)
|
||||
.add("sourcePrefixRanges", sourcePrefixRanges)
|
||||
.add("sourceType", sourceType)
|
||||
.add("sourcePorts", sourcePorts)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -351,13 +426,15 @@ public final class EnvoyServerProtoData {
|
|||
@Nullable
|
||||
private final String address;
|
||||
private final List<FilterChain> filterChains;
|
||||
private final FilterChain defaultFilterChain;
|
||||
|
||||
@VisibleForTesting
|
||||
Listener(String name, String address,
|
||||
List<FilterChain> filterChains) {
|
||||
List<FilterChain> filterChains, FilterChain defaultFilterChain) {
|
||||
this.name = name;
|
||||
this.address = address;
|
||||
this.filterChains = Collections.unmodifiableList(filterChains);
|
||||
this.defaultFilterChain = defaultFilterChain;
|
||||
}
|
||||
|
||||
private static String convertEnvoyAddressToString(Address proto) {
|
||||
|
|
@ -381,12 +458,33 @@ public final class EnvoyServerProtoData {
|
|||
List<FilterChain> filterChains = new ArrayList<>(proto.getFilterChainsCount());
|
||||
for (io.envoyproxy.envoy.config.listener.v3.FilterChain filterChain :
|
||||
proto.getFilterChainsList()) {
|
||||
filterChains.add(FilterChain.fromEnvoyProtoFilterChain(filterChain));
|
||||
if (isAcceptable(filterChain.getFilterChainMatch())) {
|
||||
filterChains.add(FilterChain.fromEnvoyProtoFilterChain(filterChain));
|
||||
}
|
||||
}
|
||||
return new Listener(
|
||||
proto.getName(),
|
||||
convertEnvoyAddressToString(proto.getAddress()),
|
||||
filterChains);
|
||||
filterChains, FilterChain.fromEnvoyProtoFilterChain(proto.getDefaultFilterChain()));
|
||||
}
|
||||
|
||||
// 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 (for now accept "managed-mtls")
|
||||
if (!filterChainMatch.getServerNamesList().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
String transportProtocol = filterChainMatch.getTransportProtocol();
|
||||
if (!transportProtocol.isEmpty() && !"raw_buffer".equals(transportProtocol)) {
|
||||
return false;
|
||||
}
|
||||
List<String> appProtocols = filterChainMatch.getApplicationProtocolsList();
|
||||
return appProtocols.isEmpty()
|
||||
|| appProtocols.contains("managed-mtls"); // TODO(sanjaypujare): remove once TD fixed
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
|
@ -401,6 +499,10 @@ public final class EnvoyServerProtoData {
|
|||
return filterChains;
|
||||
}
|
||||
|
||||
public FilterChain getDefaultFilterChain() {
|
||||
return defaultFilterChain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
|
|
@ -410,22 +512,30 @@ public final class EnvoyServerProtoData {
|
|||
return false;
|
||||
}
|
||||
Listener listener = (Listener) o;
|
||||
return java.util.Objects.equals(name, listener.name)
|
||||
&& java.util.Objects.equals(address, listener.address)
|
||||
&& java.util.Objects.equals(filterChains, listener.filterChains);
|
||||
return Objects.equals(name, listener.name)
|
||||
&& Objects.equals(address, listener.address)
|
||||
&& Objects.equals(filterChains, listener.filterChains)
|
||||
&& Objects.equals(defaultFilterChain, listener.defaultFilterChain);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return java.util.Objects.hash(name, address, filterChains);
|
||||
return Objects.hash(name, address, filterChains, defaultFilterChain);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Listener{"
|
||||
+ "name='" + name + '\''
|
||||
+ ", address='" + address + '\''
|
||||
+ ", filterChains=" + filterChains
|
||||
+ "name='"
|
||||
+ name
|
||||
+ '\''
|
||||
+ ", address='"
|
||||
+ address
|
||||
+ '\''
|
||||
+ ", filterChains="
|
||||
+ filterChains
|
||||
+ ", defaultFilterChain="
|
||||
+ defaultFilterChain
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import static com.google.common.base.Preconditions.checkState;
|
|||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.protobuf.UInt32Value;
|
||||
import io.grpc.Grpc;
|
||||
import io.grpc.Internal;
|
||||
import io.grpc.ManagedChannel;
|
||||
|
|
@ -38,14 +39,16 @@ import io.netty.channel.epoll.Epoll;
|
|||
import io.netty.channel.epoll.EpollEventLoopGroup;
|
||||
import io.netty.util.concurrent.DefaultThreadFactory;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Collections;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
|
@ -170,31 +173,199 @@ public final class XdsClientWrapperForServerSds {
|
|||
public DownstreamTlsContext getDownstreamTlsContext(Channel channel) {
|
||||
if (curListener != null && channel != null) {
|
||||
SocketAddress localAddress = channel.localAddress();
|
||||
checkState(
|
||||
localAddress instanceof InetSocketAddress,
|
||||
"Channel localAddress is expected to be InetSocketAddress");
|
||||
InetSocketAddress localInetAddr = (InetSocketAddress) localAddress;
|
||||
checkState(
|
||||
port == localInetAddr.getPort(),
|
||||
"Channel localAddress port does not match requested listener port");
|
||||
return getDownstreamTlsContext(localInetAddr);
|
||||
SocketAddress remoteAddress = channel.remoteAddress();
|
||||
if (localAddress instanceof InetSocketAddress && remoteAddress instanceof InetSocketAddress) {
|
||||
InetSocketAddress localInetAddr = (InetSocketAddress) localAddress;
|
||||
InetSocketAddress remoteInetAddr = (InetSocketAddress) remoteAddress;
|
||||
checkState(
|
||||
port == localInetAddr.getPort(),
|
||||
"Channel localAddress port does not match requested listener port");
|
||||
return getDownstreamTlsContext(localInetAddr, remoteInetAddr);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private DownstreamTlsContext getDownstreamTlsContext(InetSocketAddress localInetAddr) {
|
||||
checkNotNull(localInetAddr, "localInetAddr");
|
||||
if (curListener != null) {
|
||||
List<FilterChain> filterChains = curListener.getFilterChains();
|
||||
FilterChainComparator comparator = new FilterChainComparator(localInetAddr);
|
||||
FilterChain bestMatch =
|
||||
filterChains.isEmpty() ? null : Collections.max(filterChains, comparator);
|
||||
if (bestMatch != null
|
||||
&& (newServerApi || comparator.isMatching(bestMatch.getFilterChainMatch()))) {
|
||||
return bestMatch.getDownstreamTlsContext();
|
||||
/**
|
||||
* Using the logic specified at
|
||||
* https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/listener/listener_components.proto.html?highlight=filter%20chain#listener-filterchainmatch
|
||||
* locate a matching filter and return the corresponding DownstreamTlsContext or else return one
|
||||
* from default filter chain.
|
||||
*
|
||||
* @param localInetAddr dest address of the inbound connection
|
||||
* @param remoteInetAddr source address of the inbound connection
|
||||
*/
|
||||
private DownstreamTlsContext getDownstreamTlsContext(
|
||||
InetSocketAddress localInetAddr, InetSocketAddress remoteInetAddr) {
|
||||
List<FilterChain> filterChains = curListener.getFilterChains();
|
||||
|
||||
filterChains = filterOnDestinationPort(filterChains);
|
||||
filterChains = filterOnIpAddress(filterChains, localInetAddr.getAddress(), true);
|
||||
filterChains =
|
||||
filterOnSourceType(filterChains, remoteInetAddr.getAddress(), localInetAddr.getAddress());
|
||||
filterChains = filterOnIpAddress(filterChains, remoteInetAddr.getAddress(), false);
|
||||
filterChains = filterOnSourcePort(filterChains, remoteInetAddr.getPort());
|
||||
|
||||
// if we get more than 1, we ignore filterChains and use the defaultFilerChain
|
||||
// although spec not clear for that case
|
||||
if (filterChains.size() == 1) {
|
||||
return filterChains.get(0).getDownstreamTlsContext();
|
||||
}
|
||||
return curListener.getDefaultFilterChain().getDownstreamTlsContext();
|
||||
}
|
||||
|
||||
// destination_port present => Always fail match
|
||||
private static List<FilterChain> filterOnDestinationPort(List<FilterChain> filterChains) {
|
||||
ArrayList<FilterChain> filtered = new ArrayList<>(filterChains.size());
|
||||
for (FilterChain filterChain : filterChains) {
|
||||
FilterChainMatch filterChainMatch = filterChain.getFilterChainMatch();
|
||||
|
||||
if (filterChainMatch.getDestinationPort() == UInt32Value.getDefaultInstance().getValue()) {
|
||||
filtered.add(filterChain);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return filtered;
|
||||
}
|
||||
|
||||
private static List<FilterChain> filterOnSourcePort(
|
||||
List<FilterChain> filterChains, int sourcePort) {
|
||||
ArrayList<FilterChain> filteredOnMatch = new ArrayList<>(filterChains.size());
|
||||
ArrayList<FilterChain> filteredOnEmpty = new ArrayList<>(filterChains.size());
|
||||
for (FilterChain filterChain : filterChains) {
|
||||
FilterChainMatch filterChainMatch = filterChain.getFilterChainMatch();
|
||||
|
||||
List<Integer> sourcePortsToMatch = filterChainMatch.getSourcePorts();
|
||||
if (sourcePortsToMatch.isEmpty()) {
|
||||
filteredOnEmpty.add(filterChain);
|
||||
} else if (sourcePortsToMatch.contains(sourcePort)) {
|
||||
filteredOnMatch.add(filterChain);
|
||||
}
|
||||
}
|
||||
// match against source port is more specific than match against empty list
|
||||
return filteredOnMatch.isEmpty() ? filteredOnEmpty : filteredOnMatch;
|
||||
}
|
||||
|
||||
private List<FilterChain> filterOnSourceType(
|
||||
List<FilterChain> filterChains, InetAddress sourceAddress, InetAddress destAddress) {
|
||||
ArrayList<FilterChain> filtered = new ArrayList<>(filterChains.size());
|
||||
for (FilterChain filterChain : filterChains) {
|
||||
FilterChainMatch filterChainMatch = filterChain.getFilterChainMatch();
|
||||
EnvoyServerProtoData.ConnectionSourceType sourceType =
|
||||
filterChainMatch.getConnectionSourceType();
|
||||
|
||||
boolean matching = false;
|
||||
if (sourceType == EnvoyServerProtoData.ConnectionSourceType.SAME_IP_OR_LOOPBACK) {
|
||||
matching =
|
||||
sourceAddress.isLoopbackAddress()
|
||||
|| sourceAddress.isAnyLocalAddress()
|
||||
|| sourceAddress.equals(destAddress);
|
||||
} else if (sourceType == EnvoyServerProtoData.ConnectionSourceType.EXTERNAL) {
|
||||
matching = !sourceAddress.isLoopbackAddress() && !sourceAddress.isAnyLocalAddress();
|
||||
} else { // ANY or null
|
||||
matching = true;
|
||||
}
|
||||
if (matching) {
|
||||
filtered.add(filterChain);
|
||||
}
|
||||
}
|
||||
return filtered;
|
||||
}
|
||||
|
||||
private static boolean isCidrMatching(byte[] cidrBytes, byte[] addressBytes, int prefixLen) {
|
||||
BigInteger cidrInt = new BigInteger(cidrBytes);
|
||||
BigInteger addrInt = new BigInteger(addressBytes);
|
||||
|
||||
int shiftAmount = 8 * cidrBytes.length - prefixLen;
|
||||
|
||||
cidrInt = cidrInt.shiftRight(shiftAmount);
|
||||
addrInt = addrInt.shiftRight(shiftAmount);
|
||||
return cidrInt.equals(addrInt);
|
||||
}
|
||||
|
||||
private static class QueueElement {
|
||||
FilterChain filterChain;
|
||||
int indexOfMatchingPrefixRange;
|
||||
int matchingPrefixLength;
|
||||
|
||||
public QueueElement(FilterChain filterChain, InetAddress address, boolean forDestination) {
|
||||
this.filterChain = filterChain;
|
||||
FilterChainMatch filterChainMatch = filterChain.getFilterChainMatch();
|
||||
byte[] addressBytes = address.getAddress();
|
||||
boolean isIPv6 = address instanceof Inet6Address;
|
||||
List<CidrRange> cidrRanges =
|
||||
forDestination
|
||||
? filterChainMatch.getPrefixRanges()
|
||||
: filterChainMatch.getSourcePrefixRanges();
|
||||
indexOfMatchingPrefixRange = -1;
|
||||
if (cidrRanges.isEmpty()) { // if there is no CidrRange assume there is perfect match
|
||||
matchingPrefixLength = isIPv6 ? 128 : 32;
|
||||
} else {
|
||||
matchingPrefixLength = 0;
|
||||
int index = 0;
|
||||
for (CidrRange cidrRange : cidrRanges) {
|
||||
InetAddress cidrAddr = cidrRange.getAddressPrefix();
|
||||
boolean cidrIsIpv6 = cidrAddr instanceof Inet6Address;
|
||||
if (isIPv6 == cidrIsIpv6) {
|
||||
byte[] cidrBytes = cidrAddr.getAddress();
|
||||
int prefixLen = cidrRange.getPrefixLen();
|
||||
if (isCidrMatching(cidrBytes, addressBytes, prefixLen)
|
||||
&& prefixLen > matchingPrefixLength) {
|
||||
matchingPrefixLength = prefixLen;
|
||||
indexOfMatchingPrefixRange = index;
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class QueueElementComparator implements Comparator<QueueElement> {
|
||||
|
||||
@Override
|
||||
public int compare(QueueElement o1, QueueElement o2) {
|
||||
// descending order for max heap
|
||||
return o2.matchingPrefixLength - o1.matchingPrefixLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof QueueElementComparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
// use prefix_ranges (CIDR) and get the most specific matches
|
||||
private List<FilterChain> filterOnIpAddress(
|
||||
List<FilterChain> filterChains, InetAddress address, boolean forDestination) {
|
||||
PriorityQueue<QueueElement> heap = new PriorityQueue<>(10, new QueueElementComparator());
|
||||
|
||||
for (FilterChain filterChain : filterChains) {
|
||||
QueueElement element = new QueueElement(filterChain, address, forDestination);
|
||||
|
||||
if (element.matchingPrefixLength > 0) {
|
||||
heap.add(element);
|
||||
}
|
||||
}
|
||||
// get the top ones
|
||||
ArrayList<FilterChain> topOnes = new ArrayList<>(heap.size());
|
||||
int topMatchingPrefixLen = -1;
|
||||
while (!heap.isEmpty()) {
|
||||
QueueElement element = heap.remove();
|
||||
if (topMatchingPrefixLen == -1) {
|
||||
topMatchingPrefixLen = element.matchingPrefixLength;
|
||||
} else {
|
||||
if (element.matchingPrefixLength < topMatchingPrefixLen) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
topOnes.add(element.filterChain);
|
||||
}
|
||||
return topOnes;
|
||||
}
|
||||
|
||||
/** Adds a {@link ServerWatcher} to the list. */
|
||||
|
|
@ -204,7 +375,7 @@ public final class XdsClientWrapperForServerSds {
|
|||
serverWatchers.add(serverWatcher);
|
||||
}
|
||||
if (curListener != null) {
|
||||
serverWatcher.onSuccess(getDownstreamTlsContext(new InetSocketAddress(port)));
|
||||
serverWatcher.onSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -229,10 +400,8 @@ public final class XdsClientWrapperForServerSds {
|
|||
}
|
||||
|
||||
private void reportSuccess() {
|
||||
DownstreamTlsContext downstreamTlsContext =
|
||||
getDownstreamTlsContext(new InetSocketAddress(port));
|
||||
for (ServerWatcher watcher : getServerWatchers()) {
|
||||
watcher.onSuccess(downstreamTlsContext);
|
||||
watcher.onSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -249,97 +418,7 @@ public final class XdsClientWrapperForServerSds {
|
|||
void onError(Throwable throwable);
|
||||
|
||||
/** Called to report successful receipt of server config. */
|
||||
void onSuccess(DownstreamTlsContext downstreamTlsContext);
|
||||
}
|
||||
|
||||
private static final class FilterChainComparator implements Comparator<FilterChain> {
|
||||
private final InetSocketAddress localAddress;
|
||||
|
||||
private enum Match {
|
||||
NO_MATCH,
|
||||
EMPTY_PREFIX_RANGE_MATCH,
|
||||
IPANY_MATCH,
|
||||
EXACT_ADDRESS_MATCH
|
||||
}
|
||||
|
||||
private FilterChainComparator(InetSocketAddress localAddress) {
|
||||
checkNotNull(localAddress, "localAddress cannot be null");
|
||||
this.localAddress = localAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(FilterChain first, FilterChain second) {
|
||||
checkNotNull(first, "first arg cannot be null");
|
||||
checkNotNull(second, "second arg cannot be null");
|
||||
FilterChainMatch firstMatch = first.getFilterChainMatch();
|
||||
FilterChainMatch secondMatch = second.getFilterChainMatch();
|
||||
|
||||
if (firstMatch == null) {
|
||||
return (secondMatch == null) ? 0 : (isMatching(secondMatch) ? -1 : 1);
|
||||
} else {
|
||||
return (secondMatch == null)
|
||||
? (isMatching(firstMatch) ? 1 : -1)
|
||||
: compare(firstMatch, secondMatch);
|
||||
}
|
||||
}
|
||||
|
||||
private int compare(FilterChainMatch first, FilterChainMatch second) {
|
||||
int channelPort = localAddress.getPort();
|
||||
|
||||
if (first.getDestinationPort() == channelPort) {
|
||||
return (second.getDestinationPort() == channelPort)
|
||||
? compare(first.getPrefixRanges(), second.getPrefixRanges())
|
||||
: (isInetAddressMatching(first.getPrefixRanges()) ? 1 : 0);
|
||||
} else {
|
||||
return (second.getDestinationPort() == channelPort)
|
||||
? (isInetAddressMatching(second.getPrefixRanges()) ? -1 : 0)
|
||||
: 0;
|
||||
}
|
||||
}
|
||||
|
||||
private int compare(List<CidrRange> first, List<CidrRange> second) {
|
||||
return getInetAddressMatch(first).ordinal() - getInetAddressMatch(second).ordinal();
|
||||
}
|
||||
|
||||
private boolean isInetAddressMatching(List<CidrRange> prefixRanges) {
|
||||
return getInetAddressMatch(prefixRanges).ordinal() > Match.NO_MATCH.ordinal();
|
||||
}
|
||||
|
||||
private Match getInetAddressMatch(List<CidrRange> prefixRanges) {
|
||||
if (prefixRanges == null || prefixRanges.isEmpty()) {
|
||||
return Match.EMPTY_PREFIX_RANGE_MATCH;
|
||||
}
|
||||
InetAddress localInetAddress = localAddress.getAddress();
|
||||
for (CidrRange cidrRange : prefixRanges) {
|
||||
if (cidrRange.getPrefixLen() == 32) {
|
||||
try {
|
||||
InetAddress cidrAddr = InetAddress.getByName(cidrRange.getAddressPrefix());
|
||||
if (cidrAddr.isAnyLocalAddress()) {
|
||||
return Match.IPANY_MATCH;
|
||||
}
|
||||
if (cidrAddr.equals(localInetAddress)) {
|
||||
return Match.EXACT_ADDRESS_MATCH;
|
||||
}
|
||||
} catch (UnknownHostException e) {
|
||||
logger.log(Level.WARNING, "cidrRange address parsing", e);
|
||||
// continue
|
||||
}
|
||||
}
|
||||
// TODO(sanjaypujare): implement prefix match logic as needed
|
||||
}
|
||||
return Match.NO_MATCH;
|
||||
}
|
||||
|
||||
private boolean isMatching(FilterChainMatch filterChainMatch) {
|
||||
if (filterChainMatch == null) {
|
||||
return true;
|
||||
}
|
||||
int destPort = filterChainMatch.getDestinationPort();
|
||||
if (destPort != localAddress.getPort()) {
|
||||
return false;
|
||||
}
|
||||
return isInetAddressMatching(filterChainMatch.getPrefixRanges());
|
||||
}
|
||||
void onSuccess();
|
||||
}
|
||||
|
||||
/** Shutdown this instance and release resources. */
|
||||
|
|
|
|||
|
|
@ -92,8 +92,8 @@ public final class ServerWrapperForXds extends Server {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(EnvoyServerProtoData.DownstreamTlsContext downstreamTlsContext) {
|
||||
settableFuture.set(downstreamTlsContext);
|
||||
public void onSuccess() {
|
||||
settableFuture.set(null);
|
||||
}
|
||||
};
|
||||
xdsClientWrapperForServerSds.addServerWatcher(serverWatcher);
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ public class EnvoyServerProtoDataTest {
|
|||
.setAddress(address)
|
||||
.addFilterChains(createOutFilter())
|
||||
.addFilterChains(createInFilter())
|
||||
.setDefaultFilterChain(createDefaultFilterChain())
|
||||
.build();
|
||||
|
||||
Listener xdsListener = Listener.fromEnvoyProtoListener(listener);
|
||||
|
|
@ -81,8 +82,13 @@ public class EnvoyServerProtoDataTest {
|
|||
assertThat(inFilterChainMatch).isNotNull();
|
||||
assertThat(inFilterChainMatch.getDestinationPort()).isEqualTo(8000);
|
||||
assertThat(inFilterChainMatch.getApplicationProtocols()).containsExactly("managed-mtls");
|
||||
assertThat(inFilterChainMatch.getPrefixRanges()).containsExactly(
|
||||
new EnvoyServerProtoData.CidrRange("10.20.0.15", 32));
|
||||
assertThat(inFilterChainMatch.getPrefixRanges())
|
||||
.containsExactly(new EnvoyServerProtoData.CidrRange("10.20.0.15", 32));
|
||||
assertThat(inFilterChainMatch.getSourcePrefixRanges())
|
||||
.containsExactly(new EnvoyServerProtoData.CidrRange("10.30.3.0", 24));
|
||||
assertThat(inFilterChainMatch.getConnectionSourceType())
|
||||
.isEqualTo(EnvoyServerProtoData.ConnectionSourceType.EXTERNAL);
|
||||
assertThat(inFilterChainMatch.getSourcePorts()).containsExactly(200, 300);
|
||||
DownstreamTlsContext inFilterTlsContext = inFilter.getDownstreamTlsContext();
|
||||
assertThat(inFilterTlsContext.getCommonTlsContext()).isNotNull();
|
||||
CommonTlsContext commonTlsContext = inFilterTlsContext.getCommonTlsContext();
|
||||
|
|
@ -90,6 +96,15 @@ public class EnvoyServerProtoDataTest {
|
|||
.getTlsCertificateSdsSecretConfigsList();
|
||||
assertThat(tlsCertSdsConfigs).hasSize(1);
|
||||
assertThat(tlsCertSdsConfigs.get(0).getName()).isEqualTo("google-sds-config-default");
|
||||
|
||||
EnvoyServerProtoData.FilterChain defaultFilter = xdsListener.getDefaultFilterChain();
|
||||
assertThat(defaultFilter).isNotNull();
|
||||
EnvoyServerProtoData.FilterChainMatch defaultFilterChainMatch =
|
||||
defaultFilter.getFilterChainMatch();
|
||||
assertThat(defaultFilterChainMatch).isNotNull();
|
||||
assertThat(defaultFilterChainMatch.getDestinationPort()).isEqualTo(8001);
|
||||
assertThat(defaultFilterChainMatch.getPrefixRanges())
|
||||
.containsExactly(new EnvoyServerProtoData.CidrRange("10.20.0.16", 30));
|
||||
}
|
||||
|
||||
private static FilterChain createOutFilter() {
|
||||
|
|
@ -116,7 +131,15 @@ public class EnvoyServerProtoDataTest {
|
|||
.setAddressPrefix("10.20.0.15")
|
||||
.setPrefixLen(UInt32Value.of(32))
|
||||
.build())
|
||||
.addSourcePrefixRanges(
|
||||
CidrRange.newBuilder()
|
||||
.setAddressPrefix("10.30.3.0")
|
||||
.setPrefixLen(UInt32Value.of(24))
|
||||
.build())
|
||||
.addApplicationProtocols("managed-mtls")
|
||||
.setSourceType(FilterChainMatch.ConnectionSourceType.EXTERNAL)
|
||||
.addSourcePorts(200)
|
||||
.addSourcePorts(300)
|
||||
.build())
|
||||
.setTransportSocket(TransportSocket.newBuilder().setName("envoy.transport_sockets.tls")
|
||||
.setTypedConfig(
|
||||
|
|
@ -133,4 +156,38 @@ public class EnvoyServerProtoDataTest {
|
|||
.build();
|
||||
return filterChain;
|
||||
}
|
||||
|
||||
private static FilterChain createDefaultFilterChain() {
|
||||
FilterChain filterChain =
|
||||
FilterChain.newBuilder()
|
||||
.setFilterChainMatch(
|
||||
FilterChainMatch.newBuilder()
|
||||
.setDestinationPort(UInt32Value.of(8001))
|
||||
.addPrefixRanges(
|
||||
CidrRange.newBuilder()
|
||||
.setAddressPrefix("10.20.0.16")
|
||||
.setPrefixLen(UInt32Value.of(30))
|
||||
.build())
|
||||
.build())
|
||||
.setTransportSocket(
|
||||
TransportSocket.newBuilder()
|
||||
.setName("envoy.transport_sockets.tls")
|
||||
.setTypedConfig(
|
||||
Any.pack(
|
||||
CommonTlsContextTestsUtil.buildTestDownstreamTlsContext(
|
||||
"google-sds-config-default", "ROOTCA")))
|
||||
.build())
|
||||
.addFilters(
|
||||
Filter.newBuilder()
|
||||
.setName("envoy.http_connection_manager")
|
||||
.setTypedConfig(
|
||||
Any.newBuilder()
|
||||
.setTypeUrl(
|
||||
"type.googleapis.com/"
|
||||
+ "envoy.config.filter.network.http_connection_manager"
|
||||
+ ".v2.HttpConnectionManager"))
|
||||
.build())
|
||||
.build();
|
||||
return filterChain;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,652 @@
|
|||
/*
|
||||
* 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.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.ListenerWatcher 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.ListenerUpdate listenerUpdate =
|
||||
XdsClient.ListenerUpdate.newBuilder().setListener(listener).build();
|
||||
registeredWatcher.onListenerChanged(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.ListenerUpdate listenerUpdate =
|
||||
XdsClient.ListenerUpdate.newBuilder().setListener(listener).build();
|
||||
registeredWatcher.onListenerChanged(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.ListenerUpdate listenerUpdate =
|
||||
XdsClient.ListenerUpdate.newBuilder().setListener(listener).build();
|
||||
registeredWatcher.onListenerChanged(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.ListenerUpdate listenerUpdate =
|
||||
XdsClient.ListenerUpdate.newBuilder().setListener(listener).build();
|
||||
registeredWatcher.onListenerChanged(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.ListenerUpdate listenerUpdate =
|
||||
XdsClient.ListenerUpdate.newBuilder().setListener(listener).build();
|
||||
registeredWatcher.onListenerChanged(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.ListenerUpdate listenerUpdate =
|
||||
XdsClient.ListenerUpdate.newBuilder().setListener(listener).build();
|
||||
registeredWatcher.onListenerChanged(listenerUpdate);
|
||||
DownstreamTlsContext tlsContext1 =
|
||||
xdsClientWrapperForServerSds.getDownstreamTlsContext(channel);
|
||||
assertThat(tlsContext1).isSameInstanceAs(tlsContextForDefaultFilterChain);
|
||||
}
|
||||
|
||||
@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.ListenerUpdate listenerUpdate =
|
||||
XdsClient.ListenerUpdate.newBuilder().setListener(listener).build();
|
||||
registeredWatcher.onListenerChanged(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.ListenerUpdate listenerUpdate =
|
||||
XdsClient.ListenerUpdate.newBuilder().setListener(listener).build();
|
||||
registeredWatcher.onListenerChanged(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.ListenerUpdate listenerUpdate =
|
||||
XdsClient.ListenerUpdate.newBuilder().setListener(listener).build();
|
||||
registeredWatcher.onListenerChanged(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.ListenerUpdate listenerUpdate =
|
||||
XdsClient.ListenerUpdate.newBuilder().setListener(listener).build();
|
||||
registeredWatcher.onListenerChanged(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.ListenerUpdate listenerUpdate =
|
||||
XdsClient.ListenerUpdate.newBuilder().setListener(listener).build();
|
||||
registeredWatcher.onListenerChanged(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.ListenerUpdate listenerUpdate =
|
||||
XdsClient.ListenerUpdate.newBuilder().setListener(listener).build();
|
||||
registeredWatcher.onListenerChanged(listenerUpdate);
|
||||
DownstreamTlsContext tlsContext1 =
|
||||
xdsClientWrapperForServerSds.getDownstreamTlsContext(channel);
|
||||
assertThat(tlsContext1).isSameInstanceAs(tlsContextMoreSpecificWith2);
|
||||
}
|
||||
|
||||
@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.ListenerUpdate listenerUpdate =
|
||||
XdsClient.ListenerUpdate.newBuilder().setListener(listener).build();
|
||||
registeredWatcher.onListenerChanged(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.ListenerUpdate listenerUpdate =
|
||||
XdsClient.ListenerUpdate.newBuilder().setListener(listener).build();
|
||||
registeredWatcher.onListenerChanged(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));
|
||||
}
|
||||
}
|
||||
|
|
@ -348,6 +348,88 @@ public class ServerXdsClientNewServerApiTest {
|
|||
assertThat(fakeClock.getPendingTasks(LISTENER_RESOURCE_FETCH_TIMEOUT_TASK_FILTER)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ldsResponseWith_defaultFilterChainListener() throws InvalidProtocolBufferException {
|
||||
xdsClient.watchListenerData(PORT, listenerWatcher);
|
||||
StreamObserver<DiscoveryResponse> responseObserver = responseObservers.poll();
|
||||
StreamObserver<DiscoveryRequest> requestObserver = requestObservers.poll();
|
||||
|
||||
verify(requestObserver)
|
||||
.onNext(
|
||||
eq(
|
||||
XdsClientTestHelper.buildDiscoveryRequest(
|
||||
NODE,
|
||||
"",
|
||||
ImmutableList.of("test/value?udpa.resource.listening_address=192.168.3.7:7000"),
|
||||
ResourceType.LDS.typeUrl(),
|
||||
"")));
|
||||
assertThat(fakeClock.getPendingTasks(LISTENER_RESOURCE_FETCH_TIMEOUT_TASK_FILTER)).hasSize(1);
|
||||
|
||||
final FilterChain defaultFilterChain =
|
||||
buildFilterChain(
|
||||
buildFilterChainMatch("managed-mtls"),
|
||||
CommonTlsContextTestsUtil.buildTestDownstreamTlsContext(
|
||||
"google-sds-config-default", "ROOTCA"),
|
||||
buildTestFilter("envoy.http_connection_manager"));
|
||||
List<Any> listeners =
|
||||
ImmutableList.of(
|
||||
Any.pack(
|
||||
buildListener(
|
||||
"bar.googleapis.com",
|
||||
Any.pack(
|
||||
HttpConnectionManager.newBuilder()
|
||||
.setRouteConfig(
|
||||
buildRouteConfiguration(
|
||||
"route-bar.googleapis.com",
|
||||
ImmutableList.of(
|
||||
buildVirtualHost(
|
||||
ImmutableList.of("bar.googleapis.com"),
|
||||
"cluster-bar.googleapis.com"))))
|
||||
.build()))),
|
||||
Any.pack(
|
||||
buildListenerWithDefaultFilterChain(
|
||||
"test/value?udpa.resource.listening_address=192.168.3.7:7000",
|
||||
7000,
|
||||
"0.0.0.0",
|
||||
defaultFilterChain)));
|
||||
DiscoveryResponse response =
|
||||
buildDiscoveryResponse("0", listeners, ResourceType.LDS.typeUrl(), "0000");
|
||||
responseObserver.onNext(response);
|
||||
|
||||
// Client sends an ACK LDS request.
|
||||
verify(requestObserver)
|
||||
.onNext(
|
||||
eq(
|
||||
XdsClientTestHelper.buildDiscoveryRequest(
|
||||
NODE,
|
||||
"0",
|
||||
ImmutableList.of("test/value?udpa.resource.listening_address=192.168.3.7:7000"),
|
||||
ResourceType.LDS.typeUrl(),
|
||||
"0000")));
|
||||
|
||||
ArgumentCaptor<ListenerUpdate> listenerUpdateCaptor = ArgumentCaptor.forClass(null);
|
||||
verify(listenerWatcher, times(1)).onListenerChanged(listenerUpdateCaptor.capture());
|
||||
ListenerUpdate configUpdate = listenerUpdateCaptor.getValue();
|
||||
EnvoyServerProtoData.Listener listener = configUpdate.getListener();
|
||||
assertThat(listener.getName())
|
||||
.isEqualTo("test/value?udpa.resource.listening_address=192.168.3.7:7000");
|
||||
assertThat(listener.getAddress()).isEqualTo("0.0.0.0:7000");
|
||||
assertThat(listener.getFilterChains()).hasSize(0);
|
||||
EnvoyServerProtoData.FilterChain filterChainInboundInListenerUpdate =
|
||||
listener.getDefaultFilterChain();
|
||||
CommonTlsContext downstreamCommonTlsContext =
|
||||
filterChainInboundInListenerUpdate.getDownstreamTlsContext().getCommonTlsContext();
|
||||
assertThat(downstreamCommonTlsContext.getTlsCertificateSdsSecretConfigs(0).getName())
|
||||
.isEqualTo("google-sds-config-default");
|
||||
assertThat(
|
||||
downstreamCommonTlsContext
|
||||
.getCombinedValidationContext()
|
||||
.getValidationContextSdsSecretConfig()
|
||||
.getName())
|
||||
.isEqualTo("ROOTCA");
|
||||
assertThat(fakeClock.getPendingTasks(LISTENER_RESOURCE_FETCH_TIMEOUT_TASK_FILTER)).isEmpty();
|
||||
}
|
||||
|
||||
/** Client receives LDS responses for updating Listener previously received. */
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
|
|
@ -622,6 +704,25 @@ public class ServerXdsClientNewServerApiTest {
|
|||
backoffPolicy2, requestObserver);
|
||||
}
|
||||
|
||||
static Listener buildListenerWithDefaultFilterChain(String name, int portValue, String address,
|
||||
FilterChain defaultFilterChain) {
|
||||
io.envoyproxy.envoy.config.core.v3.Address listenerAddress =
|
||||
io.envoyproxy.envoy.config.core.v3.Address.newBuilder()
|
||||
.setSocketAddress(
|
||||
SocketAddress.newBuilder().setPortValue(portValue).setAddress(address))
|
||||
.build();
|
||||
if (defaultFilterChain == null) {
|
||||
defaultFilterChain = FilterChain.getDefaultInstance();
|
||||
}
|
||||
return
|
||||
Listener.newBuilder()
|
||||
.setName(name)
|
||||
.setAddress(listenerAddress)
|
||||
.setDefaultFilterChain(defaultFilterChain)
|
||||
.setTrafficDirection(TrafficDirection.INBOUND)
|
||||
.build();
|
||||
}
|
||||
|
||||
static Listener buildListenerWithFilterChain(String name, int portValue, String address,
|
||||
FilterChain... filterChains) {
|
||||
io.envoyproxy.envoy.config.core.v3.Address listenerAddress =
|
||||
|
|
@ -633,6 +734,7 @@ public class ServerXdsClientNewServerApiTest {
|
|||
Listener.newBuilder()
|
||||
.setName(name)
|
||||
.setAddress(listenerAddress)
|
||||
.setDefaultFilterChain(FilterChain.getDefaultInstance())
|
||||
.addAllFilterChains(Arrays.asList(filterChains))
|
||||
.setTrafficDirection(TrafficDirection.INBOUND)
|
||||
.build();
|
||||
|
|
|
|||
|
|
@ -1,213 +0,0 @@
|
|||
/*
|
||||
* Copyright 2020 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.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
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.Inet4Address;
|
||||
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.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameter;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
/** Tests for {@link XdsClientWrapperForServerSds}. */
|
||||
@RunWith(Parameterized.class)
|
||||
public class XdsClientWrapperForServerSdsTest {
|
||||
|
||||
private static final int PORT = 7000;
|
||||
|
||||
/** Iterable of various configurations to use for tests. */
|
||||
@Parameterized.Parameters(name = "{6}")
|
||||
public static Iterable<Object[]> data() {
|
||||
return Arrays.asList(
|
||||
new Object[][] {
|
||||
{
|
||||
-1, // creates null filterChainMatch for filter1
|
||||
null,
|
||||
null,
|
||||
"192.168.10.1",
|
||||
"192.168.10.2",
|
||||
1,
|
||||
"null filter chain match, expect filter1"
|
||||
},
|
||||
{
|
||||
PORT + 1,
|
||||
"192.168.10.1",
|
||||
"192.168.10.2",
|
||||
null,
|
||||
null,
|
||||
2,
|
||||
"only dest port match, expect filter2"
|
||||
},
|
||||
{
|
||||
PORT, // matches dest port
|
||||
"168.20.20.2",
|
||||
"10.1.2.3", // matches local address
|
||||
"192.168.10.1",
|
||||
"192.168.10.2",
|
||||
1,
|
||||
"dest port & address match, expect filter1"
|
||||
},
|
||||
{
|
||||
-1, // creates null filterChainMatch for filter1
|
||||
null,
|
||||
null,
|
||||
null, // empty address range for filter2
|
||||
null, // empty address range for filter2
|
||||
2,
|
||||
"empty address range over empty filterChainMatch, expect filter2"
|
||||
},
|
||||
{
|
||||
PORT,
|
||||
null,
|
||||
null,
|
||||
"192.168.1.4",
|
||||
"0.0.0.0", // IPANY for filter2
|
||||
2,
|
||||
"IPANY over empty address match, expect filter2"
|
||||
},
|
||||
{
|
||||
PORT,
|
||||
"192.168.1.4",
|
||||
"0.0.0.0", // IPANY for filter1
|
||||
"168.154.4.7",
|
||||
"10.1.2.3", // matches local address
|
||||
2,
|
||||
"exact IP over IPANY match, expect filter2"
|
||||
},
|
||||
{
|
||||
PORT, // matches dest port but no address match
|
||||
"168.20.20.2",
|
||||
"10.1.2.4",
|
||||
"192.168.10.1",
|
||||
"192.168.10.2",
|
||||
0,
|
||||
"dest port match but no address match, expect null"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Parameter(0)
|
||||
public int destPort1;
|
||||
@Parameter(1)
|
||||
public String addressPrefix11;
|
||||
@Parameter(2)
|
||||
public String addressPrefix12;
|
||||
@Parameter(3)
|
||||
public String addressPrefix21;
|
||||
@Parameter(4)
|
||||
public String addressPrefix22;
|
||||
@Parameter(5)
|
||||
public int expectedIndex;
|
||||
@Parameter(6)
|
||||
public String testName;
|
||||
|
||||
@Mock private XdsClient xdsClient;
|
||||
@Mock private Channel channel;
|
||||
|
||||
private XdsClientWrapperForServerSds xdsClientWrapperForServerSds;
|
||||
private final DownstreamTlsContext[] tlsContexts = new DownstreamTlsContext[3];
|
||||
|
||||
/** Creates XdsClientWrapperForServerSds: also used by other classes. */
|
||||
public static XdsClientWrapperForServerSds createXdsClientWrapperForServerSds(
|
||||
int port, DownstreamTlsContext downstreamTlsContext) {
|
||||
XdsClient mockXdsClient = mock(XdsClient.class);
|
||||
XdsClientWrapperForServerSds xdsClientWrapperForServerSds =
|
||||
new XdsClientWrapperForServerSds(port);
|
||||
xdsClientWrapperForServerSds.start(mockXdsClient);
|
||||
generateListenerUpdateToWatcher(
|
||||
port, downstreamTlsContext, xdsClientWrapperForServerSds.getListenerWatcher());
|
||||
return xdsClientWrapperForServerSds;
|
||||
}
|
||||
|
||||
static void generateListenerUpdateToWatcher(
|
||||
int port, DownstreamTlsContext tlsContext, XdsClient.ListenerWatcher registeredWatcher) {
|
||||
EnvoyServerProtoData.Listener listener =
|
||||
XdsSdsClientServerTest.buildListener("listener1", "0.0.0.0", port, tlsContext);
|
||||
XdsClient.ListenerUpdate listenerUpdate =
|
||||
XdsClient.ListenerUpdate.newBuilder().setListener(listener).build();
|
||||
registeredWatcher.onListenerChanged(listenerUpdate);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws IOException {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
xdsClientWrapperForServerSds = new XdsClientWrapperForServerSds(PORT);
|
||||
xdsClientWrapperForServerSds.start(xdsClient);
|
||||
tlsContexts[0] = null;
|
||||
tlsContexts[1] =
|
||||
CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1");
|
||||
tlsContexts[2] =
|
||||
CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT2", "VA2");
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
xdsClientWrapperForServerSds.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Common method called by most tests. Creates 2 filterChains each with 2 addresses. First
|
||||
* filterChain's destPort is always PORT.
|
||||
*/
|
||||
@Test
|
||||
public void commonFilterChainMatchTest()
|
||||
throws UnknownHostException {
|
||||
ArgumentCaptor<XdsClient.ListenerWatcher> listenerWatcherCaptor = ArgumentCaptor.forClass(null);
|
||||
verify(xdsClient).watchListenerData(eq(PORT), listenerWatcherCaptor.capture());
|
||||
XdsClient.ListenerWatcher registeredWatcher = listenerWatcherCaptor.getValue();
|
||||
InetAddress ipLocalAddress = Inet4Address.getByName("10.1.2.3");
|
||||
InetSocketAddress localAddress = new InetSocketAddress(ipLocalAddress, PORT);
|
||||
when(channel.localAddress()).thenReturn(localAddress);
|
||||
EnvoyServerProtoData.Listener listener =
|
||||
XdsServerTestHelper.buildTestListener(
|
||||
"listener1",
|
||||
"10.1.2.3",
|
||||
destPort1,
|
||||
PORT,
|
||||
addressPrefix11,
|
||||
addressPrefix12,
|
||||
addressPrefix21,
|
||||
addressPrefix22,
|
||||
tlsContexts[1],
|
||||
tlsContexts[2]);
|
||||
XdsClient.ListenerUpdate listenerUpdate =
|
||||
XdsClient.ListenerUpdate.newBuilder().setListener(listener).build();
|
||||
registeredWatcher.onListenerChanged(listenerUpdate);
|
||||
DownstreamTlsContext downstreamTlsContext =
|
||||
xdsClientWrapperForServerSds.getDownstreamTlsContext(channel);
|
||||
assertThat(downstreamTlsContext).isSameInstanceAs(tlsContexts[expectedIndex]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -23,7 +23,6 @@ import static org.mockito.ArgumentMatchers.eq;
|
|||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.same;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
|
@ -79,28 +78,20 @@ public class XdsClientWrapperForServerSdsTestMisc {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void nonInetSocketAddress_expectException() {
|
||||
public void nonInetSocketAddress_expectNull() throws UnknownHostException {
|
||||
registeredWatcher =
|
||||
XdsServerTestHelper.startAndGetWatcher(xdsClientWrapperForServerSds, xdsClient, PORT);
|
||||
try {
|
||||
DownstreamTlsContext unused =
|
||||
sendListenerUpdate(new InProcessSocketAddress("test1"), null, null);
|
||||
fail("exception expected");
|
||||
} catch (IllegalStateException expected) {
|
||||
assertThat(expected)
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Channel localAddress is expected to be InetSocketAddress");
|
||||
}
|
||||
XdsServerTestHelper.startAndGetWatcher(xdsClientWrapperForServerSds, xdsClient, PORT);
|
||||
assertThat(sendListenerUpdate(new InProcessSocketAddress("test1"), null)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nonMatchingPort_expectException() throws UnknownHostException {
|
||||
registeredWatcher =
|
||||
XdsServerTestHelper.startAndGetWatcher(xdsClientWrapperForServerSds, xdsClient, PORT);
|
||||
XdsServerTestHelper.startAndGetWatcher(xdsClientWrapperForServerSds, xdsClient, PORT);
|
||||
try {
|
||||
InetAddress ipLocalAddress = InetAddress.getByName("10.1.2.3");
|
||||
InetSocketAddress localAddress = new InetSocketAddress(ipLocalAddress, PORT + 1);
|
||||
DownstreamTlsContext unused = sendListenerUpdate(localAddress, null, null);
|
||||
DownstreamTlsContext unused = sendListenerUpdate(localAddress, null);
|
||||
fail("exception expected");
|
||||
} catch (IllegalStateException expected) {
|
||||
assertThat(expected)
|
||||
|
|
@ -121,7 +112,10 @@ public class XdsClientWrapperForServerSdsTestMisc {
|
|||
when(channel.localAddress()).thenReturn(localAddress);
|
||||
EnvoyServerProtoData.Listener listener =
|
||||
new EnvoyServerProtoData.Listener(
|
||||
"listener1", "10.1.2.3", Collections.<EnvoyServerProtoData.FilterChain>emptyList());
|
||||
"listener1",
|
||||
"10.1.2.3",
|
||||
Collections.<EnvoyServerProtoData.FilterChain>emptyList(),
|
||||
null);
|
||||
XdsClient.ListenerUpdate listenerUpdate =
|
||||
XdsClient.ListenerUpdate.newBuilder().setListener(listener).build();
|
||||
registeredWatcher.onListenerChanged(listenerUpdate);
|
||||
|
|
@ -141,10 +135,10 @@ public class XdsClientWrapperForServerSdsTestMisc {
|
|||
EnvoyServerProtoData.DownstreamTlsContext tlsContext =
|
||||
CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1");
|
||||
verify(mockServerWatcher, never())
|
||||
.onSuccess(any(EnvoyServerProtoData.DownstreamTlsContext.class));
|
||||
DownstreamTlsContext returnedTlsContext = sendListenerUpdate(localAddress, tlsContext, null);
|
||||
.onSuccess();
|
||||
DownstreamTlsContext returnedTlsContext = sendListenerUpdate(localAddress, tlsContext);
|
||||
assertThat(returnedTlsContext).isSameInstanceAs(tlsContext);
|
||||
verify(mockServerWatcher).onSuccess(same(tlsContext));
|
||||
verify(mockServerWatcher).onSuccess();
|
||||
xdsClientWrapperForServerSds.removeServerWatcher(mockServerWatcher);
|
||||
}
|
||||
|
||||
|
|
@ -156,12 +150,12 @@ public class XdsClientWrapperForServerSdsTestMisc {
|
|||
InetSocketAddress localAddress = new InetSocketAddress(ipLocalAddress, PORT);
|
||||
EnvoyServerProtoData.DownstreamTlsContext tlsContext =
|
||||
CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1");
|
||||
DownstreamTlsContext returnedTlsContext = sendListenerUpdate(localAddress, tlsContext, null);
|
||||
DownstreamTlsContext returnedTlsContext = sendListenerUpdate(localAddress, tlsContext);
|
||||
assertThat(returnedTlsContext).isSameInstanceAs(tlsContext);
|
||||
XdsClientWrapperForServerSds.ServerWatcher mockServerWatcher =
|
||||
mock(XdsClientWrapperForServerSds.ServerWatcher.class);
|
||||
xdsClientWrapperForServerSds.addServerWatcher(mockServerWatcher);
|
||||
verify(mockServerWatcher).onSuccess(same(tlsContext));
|
||||
verify(mockServerWatcher).onSuccess();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -192,10 +186,10 @@ public class XdsClientWrapperForServerSdsTestMisc {
|
|||
EnvoyServerProtoData.DownstreamTlsContext tlsContext =
|
||||
CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1");
|
||||
verify(mockServerWatcher, never())
|
||||
.onSuccess(any(EnvoyServerProtoData.DownstreamTlsContext.class));
|
||||
DownstreamTlsContext returnedTlsContext = sendListenerUpdate(localAddress, tlsContext, null);
|
||||
.onSuccess();
|
||||
DownstreamTlsContext returnedTlsContext = sendListenerUpdate(localAddress, tlsContext);
|
||||
assertThat(returnedTlsContext).isSameInstanceAs(tlsContext);
|
||||
verify(mockServerWatcher).onSuccess(same(tlsContext));
|
||||
verify(mockServerWatcher).onSuccess();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -215,12 +209,24 @@ public class XdsClientWrapperForServerSdsTestMisc {
|
|||
}
|
||||
|
||||
private DownstreamTlsContext sendListenerUpdate(
|
||||
SocketAddress localAddress,
|
||||
DownstreamTlsContext tlsContext1,
|
||||
DownstreamTlsContext tlsContext2) {
|
||||
SocketAddress localAddress, DownstreamTlsContext tlsContext) throws UnknownHostException {
|
||||
when(channel.localAddress()).thenReturn(localAddress);
|
||||
XdsServerTestHelper.generateListenerUpdate(
|
||||
registeredWatcher, PORT, tlsContext1, tlsContext2);
|
||||
InetAddress ipRemoteAddress = InetAddress.getByName("10.4.5.6");
|
||||
InetSocketAddress remoteAddress = new InetSocketAddress(ipRemoteAddress, 1234);
|
||||
when(channel.remoteAddress()).thenReturn(remoteAddress);
|
||||
XdsServerTestHelper.generateListenerUpdate(registeredWatcher, tlsContext);
|
||||
return xdsClientWrapperForServerSds.getDownstreamTlsContext(channel);
|
||||
}
|
||||
|
||||
/** Creates XdsClientWrapperForServerSds: also used by other classes. */
|
||||
public static XdsClientWrapperForServerSds createXdsClientWrapperForServerSds(
|
||||
int port, DownstreamTlsContext downstreamTlsContext) {
|
||||
XdsClient mockXdsClient = mock(XdsClient.class);
|
||||
XdsClientWrapperForServerSds xdsClientWrapperForServerSds =
|
||||
new XdsClientWrapperForServerSds(port);
|
||||
xdsClientWrapperForServerSds.start(mockXdsClient);
|
||||
XdsSdsClientServerTest.generateListenerUpdateToWatcher(
|
||||
downstreamTlsContext, xdsClientWrapperForServerSds.getListenerWatcher());
|
||||
return xdsClientWrapperForServerSds;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
package io.grpc.xds;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static io.grpc.xds.XdsServerTestHelper.buildFilterChainMatch;
|
||||
import static io.grpc.xds.internal.sds.CommonTlsContextTestsUtil.BAD_CLIENT_KEY_FILE;
|
||||
import static io.grpc.xds.internal.sds.CommonTlsContextTestsUtil.BAD_CLIENT_PEM_FILE;
|
||||
import static io.grpc.xds.internal.sds.CommonTlsContextTestsUtil.BAD_SERVER_KEY_FILE;
|
||||
|
|
@ -293,8 +292,7 @@ public class XdsSdsClientServerTest {
|
|||
DownstreamTlsContext downstreamTlsContext =
|
||||
CommonTlsContextTestsUtil.buildDownstreamTlsContextFromFilenames(
|
||||
BAD_SERVER_KEY_FILE, BAD_SERVER_PEM_FILE, CA_PEM_FILE);
|
||||
XdsClientWrapperForServerSdsTest.generateListenerUpdateToWatcher(
|
||||
port, downstreamTlsContext, listenerWatcher);
|
||||
generateListenerUpdateToWatcher(downstreamTlsContext, listenerWatcher);
|
||||
try {
|
||||
SimpleServiceGrpc.SimpleServiceBlockingStub blockingStub =
|
||||
getBlockingStub(upstreamTlsContext, "foo.test.google.fr");
|
||||
|
|
@ -314,8 +312,7 @@ public class XdsSdsClientServerTest {
|
|||
SERVER_1_KEY_FILE, SERVER_1_PEM_FILE, CA_PEM_FILE);
|
||||
|
||||
final XdsClientWrapperForServerSds xdsClientWrapperForServerSds =
|
||||
XdsClientWrapperForServerSdsTest.createXdsClientWrapperForServerSds(
|
||||
port, /* downstreamTlsContext= */ downstreamTlsContext);
|
||||
createXdsClientWrapperForServerSds(port);
|
||||
buildServerWithFallbackServerCredentials(
|
||||
xdsClientWrapperForServerSds, InsecureServerCredentials.create(), downstreamTlsContext);
|
||||
|
||||
|
|
@ -353,6 +350,23 @@ public class XdsSdsClientServerTest {
|
|||
buildServer(port, xdsCredentials, xdsClientWrapperForServerSds, downstreamTlsContext);
|
||||
}
|
||||
|
||||
/** Creates XdsClientWrapperForServerSds. */
|
||||
private static XdsClientWrapperForServerSds createXdsClientWrapperForServerSds(int port) {
|
||||
XdsClient mockXdsClient = mock(XdsClient.class);
|
||||
XdsClientWrapperForServerSds xdsClientWrapperForServerSds =
|
||||
new XdsClientWrapperForServerSds(port);
|
||||
xdsClientWrapperForServerSds.start(mockXdsClient);
|
||||
return xdsClientWrapperForServerSds;
|
||||
}
|
||||
|
||||
static void generateListenerUpdateToWatcher(
|
||||
DownstreamTlsContext tlsContext, XdsClient.ListenerWatcher registeredWatcher) {
|
||||
EnvoyServerProtoData.Listener listener = buildListener("listener1", "0.0.0.0", tlsContext);
|
||||
XdsClient.ListenerUpdate listenerUpdate =
|
||||
XdsClient.ListenerUpdate.newBuilder().setListener(listener).build();
|
||||
registeredWatcher.onListenerChanged(listenerUpdate);
|
||||
}
|
||||
|
||||
private void buildServer(
|
||||
int port,
|
||||
ServerCredentials serverCredentials,
|
||||
|
|
@ -362,20 +376,24 @@ public class XdsSdsClientServerTest {
|
|||
XdsServerBuilder builder = XdsServerBuilder.forPort(port, serverCredentials)
|
||||
.addService(new SimpleServiceImpl());
|
||||
XdsServerTestHelper.generateListenerUpdate(
|
||||
xdsClientWrapperForServerSds.getListenerWatcher(),
|
||||
port,
|
||||
downstreamTlsContext,
|
||||
/* tlsContext2= */null);
|
||||
xdsClientWrapperForServerSds.getListenerWatcher(), downstreamTlsContext);
|
||||
cleanupRule.register(builder.buildServer(xdsClientWrapperForServerSds)).start();
|
||||
}
|
||||
|
||||
static EnvoyServerProtoData.Listener buildListener(
|
||||
String name, String address, int port, DownstreamTlsContext tlsContext) {
|
||||
EnvoyServerProtoData.FilterChainMatch filterChainMatch = buildFilterChainMatch(port, address);
|
||||
EnvoyServerProtoData.FilterChain filterChain1 =
|
||||
String name, String address, DownstreamTlsContext tlsContext) {
|
||||
EnvoyServerProtoData.FilterChainMatch filterChainMatch =
|
||||
new EnvoyServerProtoData.FilterChainMatch(
|
||||
0,
|
||||
Arrays.<EnvoyServerProtoData.CidrRange>asList(),
|
||||
Arrays.<String>asList(),
|
||||
Arrays.<EnvoyServerProtoData.CidrRange>asList(),
|
||||
null,
|
||||
Arrays.<Integer>asList());
|
||||
EnvoyServerProtoData.FilterChain defaultFilterChain =
|
||||
new EnvoyServerProtoData.FilterChain(filterChainMatch, tlsContext);
|
||||
EnvoyServerProtoData.Listener listener =
|
||||
new EnvoyServerProtoData.Listener(name, address, Arrays.asList(filterChain1));
|
||||
new EnvoyServerProtoData.Listener(name, address, Arrays.asList(defaultFilterChain), null);
|
||||
return listener;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -144,9 +144,8 @@ public class XdsServerBuilderTest {
|
|||
Future<Throwable> future = startServerAsync();
|
||||
XdsServerTestHelper.generateListenerUpdate(
|
||||
listenerWatcher,
|
||||
port,
|
||||
CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"),
|
||||
null);
|
||||
CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1")
|
||||
);
|
||||
verifyServer(future, null, null);
|
||||
verifyShutdown();
|
||||
}
|
||||
|
|
@ -157,9 +156,8 @@ public class XdsServerBuilderTest {
|
|||
buildServer(null, true);
|
||||
XdsServerTestHelper.generateListenerUpdate(
|
||||
listenerWatcher,
|
||||
port,
|
||||
CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"),
|
||||
null);
|
||||
CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1")
|
||||
);
|
||||
xdsServer.start();
|
||||
try {
|
||||
xdsServer.start();
|
||||
|
|
@ -180,9 +178,8 @@ public class XdsServerBuilderTest {
|
|||
Future<Throwable> future = startServerAsync();
|
||||
XdsServerTestHelper.generateListenerUpdate(
|
||||
listenerWatcher,
|
||||
port,
|
||||
CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"),
|
||||
null);
|
||||
CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1")
|
||||
);
|
||||
verifyServer(future, mockXdsServingStatusListener, null);
|
||||
verifyShutdown();
|
||||
}
|
||||
|
|
@ -217,9 +214,8 @@ public class XdsServerBuilderTest {
|
|||
reset(mockXdsServingStatusListener);
|
||||
XdsServerTestHelper.generateListenerUpdate(
|
||||
listenerWatcher,
|
||||
port,
|
||||
CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"),
|
||||
null);
|
||||
CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1")
|
||||
);
|
||||
verifyServer(future, mockXdsServingStatusListener, null);
|
||||
verifyShutdown();
|
||||
}
|
||||
|
|
@ -235,9 +231,8 @@ public class XdsServerBuilderTest {
|
|||
ServerSocket serverSocket = new ServerSocket(port);
|
||||
XdsServerTestHelper.generateListenerUpdate(
|
||||
listenerWatcher,
|
||||
port,
|
||||
CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"),
|
||||
null);
|
||||
CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1")
|
||||
);
|
||||
Throwable exception = future.get(5, TimeUnit.SECONDS);
|
||||
assertThat(exception).isInstanceOf(IOException.class);
|
||||
assertThat(exception).hasMessageThat().contains("Failed to bind");
|
||||
|
|
@ -269,14 +264,12 @@ public class XdsServerBuilderTest {
|
|||
Future<Throwable> future = startServerAsync();
|
||||
XdsServerTestHelper.generateListenerUpdate(
|
||||
listenerWatcher,
|
||||
port,
|
||||
CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"),
|
||||
null);
|
||||
CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1")
|
||||
);
|
||||
XdsServerTestHelper.generateListenerUpdate(
|
||||
listenerWatcher,
|
||||
port,
|
||||
CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1"),
|
||||
null);
|
||||
CommonTlsContextTestsUtil.buildTestInternalDownstreamTlsContext("CERT1", "VA1")
|
||||
);
|
||||
verify(mockXdsServingStatusListener, never()).onNotServing(any(Throwable.class));
|
||||
verifyServer(future, mockXdsServingStatusListener, null);
|
||||
listenerWatcher.onError(Status.ABORTED);
|
||||
|
|
|
|||
|
|
@ -19,12 +19,9 @@ package io.grpc.xds;
|
|||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
/**
|
||||
|
|
@ -43,31 +40,17 @@ class XdsServerTestHelper {
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link XdsClient.ListenerUpdate} with maximum of 2
|
||||
* {@link io.grpc.xds.EnvoyServerProtoData.FilterChain} each one with a destination port and an
|
||||
* optional {@link EnvoyServerProtoData.DownstreamTlsContext}.
|
||||
* @param registeredWatcher the watcher on which to generate the update
|
||||
* @param destPort if > 0 to create both the {@link EnvoyServerProtoData.FilterChain}
|
||||
* @param tlsContext1 if non-null, used to populate the 1st filterChain
|
||||
* @param tlsContext2 if non-null, used to populate the 2nd filterChain
|
||||
* Creates a {@link XdsClient.ListenerUpdate} with {@link
|
||||
* io.grpc.xds.EnvoyServerProtoData.FilterChain} with a destination port and an optional {@link
|
||||
* EnvoyServerProtoData.DownstreamTlsContext}.
|
||||
*
|
||||
* @param registeredWatcher the watcher on which to generate the update
|
||||
* @param tlsContext if non-null, used to populate filterChain
|
||||
*/
|
||||
static void generateListenerUpdate(
|
||||
XdsClient.ListenerWatcher registeredWatcher,
|
||||
int destPort,
|
||||
EnvoyServerProtoData.DownstreamTlsContext tlsContext1,
|
||||
EnvoyServerProtoData.DownstreamTlsContext tlsContext2) {
|
||||
EnvoyServerProtoData.Listener listener =
|
||||
buildTestListener(
|
||||
"listener1",
|
||||
"10.1.2.3",
|
||||
destPort,
|
||||
destPort,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
tlsContext1,
|
||||
tlsContext2);
|
||||
XdsClient.ListenerWatcher registeredWatcher,
|
||||
EnvoyServerProtoData.DownstreamTlsContext tlsContext) {
|
||||
EnvoyServerProtoData.Listener listener = buildTestListener("listener1", "10.1.2.3", tlsContext);
|
||||
XdsClient.ListenerUpdate listenerUpdate =
|
||||
XdsClient.ListenerUpdate.newBuilder().setListener(listener).build();
|
||||
registeredWatcher.onListenerChanged(listenerUpdate);
|
||||
|
|
@ -81,38 +64,22 @@ class XdsServerTestHelper {
|
|||
}
|
||||
|
||||
static EnvoyServerProtoData.Listener buildTestListener(
|
||||
String name,
|
||||
String address,
|
||||
int destPort1,
|
||||
int destPort2,
|
||||
String addressPrefix11,
|
||||
String addressPrefix12,
|
||||
String addressPrefix21,
|
||||
String addressPrefix22,
|
||||
EnvoyServerProtoData.DownstreamTlsContext tlsContext1,
|
||||
EnvoyServerProtoData.DownstreamTlsContext tlsContext2) {
|
||||
String name, String address, EnvoyServerProtoData.DownstreamTlsContext tlsContext) {
|
||||
EnvoyServerProtoData.FilterChainMatch filterChainMatch1 =
|
||||
destPort1 > 0 ? buildFilterChainMatch(destPort1, addressPrefix11, addressPrefix12) : null;
|
||||
EnvoyServerProtoData.FilterChainMatch filterChainMatch2 =
|
||||
destPort2 > 0 ? buildFilterChainMatch(destPort2, addressPrefix21, addressPrefix22) : null;
|
||||
new EnvoyServerProtoData.FilterChainMatch(
|
||||
0,
|
||||
Arrays.<EnvoyServerProtoData.CidrRange>asList(),
|
||||
Arrays.<String>asList(),
|
||||
Arrays.<EnvoyServerProtoData.CidrRange>asList(),
|
||||
null,
|
||||
Arrays.<Integer>asList());
|
||||
EnvoyServerProtoData.FilterChain filterChain1 =
|
||||
new EnvoyServerProtoData.FilterChain(filterChainMatch1, tlsContext1);
|
||||
EnvoyServerProtoData.FilterChain filterChain2 =
|
||||
new EnvoyServerProtoData.FilterChain(filterChainMatch2, tlsContext2);
|
||||
new EnvoyServerProtoData.FilterChain(filterChainMatch1, tlsContext);
|
||||
EnvoyServerProtoData.FilterChain defaultFilterChain =
|
||||
new EnvoyServerProtoData.FilterChain(null, null);
|
||||
EnvoyServerProtoData.Listener listener =
|
||||
new EnvoyServerProtoData.Listener(name, address, Arrays.asList(filterChain1, filterChain2));
|
||||
new EnvoyServerProtoData.Listener(
|
||||
name, address, Arrays.asList(filterChain1), defaultFilterChain);
|
||||
return listener;
|
||||
}
|
||||
|
||||
static EnvoyServerProtoData.FilterChainMatch buildFilterChainMatch(
|
||||
int destPort, String... addressPrefix) {
|
||||
ArrayList<EnvoyServerProtoData.CidrRange> prefixRanges = new ArrayList<>();
|
||||
for (String address : addressPrefix) {
|
||||
if (!Strings.isNullOrEmpty(address)) {
|
||||
prefixRanges.add(new EnvoyServerProtoData.CidrRange(address, 32));
|
||||
}
|
||||
}
|
||||
return new EnvoyServerProtoData.FilterChainMatch(
|
||||
destPort, prefixRanges, Arrays.<String>asList());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ import io.grpc.xds.EnvoyServerProtoData.DownstreamTlsContext;
|
|||
import io.grpc.xds.EnvoyServerProtoData.UpstreamTlsContext;
|
||||
import io.grpc.xds.InternalXdsAttributes;
|
||||
import io.grpc.xds.XdsClientWrapperForServerSds;
|
||||
import io.grpc.xds.XdsClientWrapperForServerSdsTest;
|
||||
import io.grpc.xds.XdsClientWrapperForServerSdsTestMisc;
|
||||
import io.grpc.xds.internal.sds.SdsProtocolNegotiators.ClientSdsHandler;
|
||||
import io.grpc.xds.internal.sds.SdsProtocolNegotiators.ClientSdsProtocolNegotiator;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
|
|
@ -227,13 +227,18 @@ public class SdsProtocolNegotiatorsTest {
|
|||
public SocketAddress localAddress() {
|
||||
return new InetSocketAddress("172.168.1.1", 80);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SocketAddress remoteAddress() {
|
||||
return new InetSocketAddress("172.168.2.2", 90);
|
||||
}
|
||||
};
|
||||
pipeline = channel.pipeline();
|
||||
DownstreamTlsContext downstreamTlsContext =
|
||||
buildDownstreamTlsContextFromFilenames(SERVER_1_KEY_FILE, SERVER_1_PEM_FILE, CA_PEM_FILE);
|
||||
|
||||
XdsClientWrapperForServerSds xdsClientWrapperForServerSds =
|
||||
XdsClientWrapperForServerSdsTest.createXdsClientWrapperForServerSds(
|
||||
XdsClientWrapperForServerSdsTestMisc.createXdsClientWrapperForServerSds(
|
||||
80, downstreamTlsContext);
|
||||
SdsProtocolNegotiators.HandlerPickerHandler handlerPickerHandler =
|
||||
new SdsProtocolNegotiators.HandlerPickerHandler(grpcHandler, xdsClientWrapperForServerSds,
|
||||
|
|
@ -281,7 +286,7 @@ public class SdsProtocolNegotiatorsTest {
|
|||
.getDefaultInstance());
|
||||
|
||||
XdsClientWrapperForServerSds xdsClientWrapperForServerSds =
|
||||
XdsClientWrapperForServerSdsTest.createXdsClientWrapperForServerSds(
|
||||
XdsClientWrapperForServerSdsTestMisc.createXdsClientWrapperForServerSds(
|
||||
80, downstreamTlsContext);
|
||||
SdsProtocolNegotiators.HandlerPickerHandler handlerPickerHandler =
|
||||
new SdsProtocolNegotiators.HandlerPickerHandler(
|
||||
|
|
|
|||
Loading…
Reference in New Issue