-
Notifications
You must be signed in to change notification settings - Fork 3.9k
xds: listener type validation #11933
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4eb625a
ad90963
01927a6
8780c52
76270a4
da0d5ab
ba8af22
694c2f1
506bbe4
87aad6f
239f167
ca5bb14
cb41652
e07158f
9f79e8c
d8fb13a
6873d59
b3908f1
4dc1039
3a36c2d
f82d899
eee4ea9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -162,13 +162,16 @@ static EnvoyServerProtoData.Listener parseServerSideListener( | |
} | ||
|
||
String address = null; | ||
SocketAddress socketAddress = null; | ||
if (proto.getAddress().hasSocketAddress()) { | ||
SocketAddress socketAddress = proto.getAddress().getSocketAddress(); | ||
socketAddress = proto.getAddress().getSocketAddress(); | ||
address = socketAddress.getAddress(); | ||
if (address.isEmpty()) { | ||
throw new ResourceInvalidException("Invalid address: Empty address is not allowed."); | ||
} | ||
switch (socketAddress.getPortSpecifierCase()) { | ||
case NAMED_PORT: | ||
address = address + ":" + socketAddress.getNamedPort(); | ||
break; | ||
throw new ResourceInvalidException("NAMED_PORT is not supported in gRPC."); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add unit test in GrpcXdsClientImplDataTest. |
||
case PORT_VALUE: | ||
address = address + ":" + socketAddress.getPortValue(); | ||
break; | ||
|
@@ -209,8 +212,8 @@ static EnvoyServerProtoData.Listener parseServerSideListener( | |
null, certProviderInstances, args); | ||
} | ||
|
||
return EnvoyServerProtoData.Listener.create( | ||
proto.getName(), address, filterChains.build(), defaultFilterChain); | ||
return EnvoyServerProtoData.Listener.create(proto.getName(), address, filterChains.build(), | ||
defaultFilterChain, socketAddress == null ? null : socketAddress.getProtocol()); | ||
} | ||
|
||
@VisibleForTesting | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -676,6 +676,13 @@ public void onUpdate(StatusOr<XdsConfig> updateOrStatus) { | |
// Process Route | ||
XdsConfig update = updateOrStatus.getValue(); | ||
HttpConnectionManager httpConnectionManager = update.getListener().httpConnectionManager(); | ||
if (httpConnectionManager == null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add unit test for when the listener update is missing httpConnectionManager. |
||
logger.log(XdsLogLevel.INFO, "API Listener: httpConnectionManager does not exist."); | ||
updateActiveFilters(null); | ||
cleanUpRoutes(updateOrStatus.getStatus()); | ||
return; | ||
} | ||
|
||
VirtualHost virtualHost = update.getVirtualHost(); | ||
ImmutableList<NamedFilterConfig> filterConfigs = httpConnectionManager.httpFilterConfigs(); | ||
long streamDurationNano = httpConnectionManager.httpMaxStreamDurationNano(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,7 +24,10 @@ | |
import com.google.common.annotations.VisibleForTesting; | ||
import com.google.common.collect.ImmutableList; | ||
import com.google.common.collect.ImmutableMap; | ||
import com.google.common.net.HostAndPort; | ||
import com.google.common.net.InetAddresses; | ||
import com.google.common.util.concurrent.SettableFuture; | ||
import io.envoyproxy.envoy.config.core.v3.SocketAddress.Protocol; | ||
import io.grpc.Attributes; | ||
import io.grpc.InternalServerInterceptors; | ||
import io.grpc.Metadata; | ||
|
@@ -57,6 +60,7 @@ | |
import io.grpc.xds.client.XdsClient.ResourceWatcher; | ||
import io.grpc.xds.internal.security.SslContextProviderSupplier; | ||
import java.io.IOException; | ||
import java.net.InetAddress; | ||
import java.net.SocketAddress; | ||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
|
@@ -383,7 +387,21 @@ public void onChanged(final LdsUpdate update) { | |
return; | ||
} | ||
logger.log(Level.FINEST, "Received Lds update {0}", update); | ||
checkNotNull(update.listener(), "update"); | ||
if (update.listener() == null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add unit test for this case as well. |
||
onResourceDoesNotExist("Non-API"); | ||
return; | ||
} | ||
|
||
String ldsAddress = update.listener().address(); | ||
ejona86 marked this conversation as resolved.
Show resolved
Hide resolved
ejona86 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (ldsAddress == null || update.listener().protocol() != Protocol.TCP | ||
|| !ipAddressesMatch(ldsAddress)) { | ||
handleConfigNotFoundOrMismatch( | ||
Status.UNKNOWN.withDescription( | ||
String.format( | ||
"Listener address mismatch: expected %s, but got %s.", | ||
listenerAddress, ldsAddress)).asException()); | ||
return; | ||
} | ||
if (!pendingRds.isEmpty()) { | ||
// filter chain state has not yet been applied to filterChainSelectorManager and there | ||
// are two sets of sslContextProviderSuppliers, so we release the old ones. | ||
|
@@ -432,6 +450,18 @@ public void onChanged(final LdsUpdate update) { | |
} | ||
} | ||
|
||
private boolean ipAddressesMatch(String ldsAddress) { | ||
HostAndPort ldsAddressHnP = HostAndPort.fromString(ldsAddress); | ||
kannanjgithub marked this conversation as resolved.
Show resolved
Hide resolved
|
||
HostAndPort listenerAddressHnP = HostAndPort.fromString(listenerAddress); | ||
if (!ldsAddressHnP.hasPort() || !listenerAddressHnP.hasPort() | ||
|| ldsAddressHnP.getPort() != listenerAddressHnP.getPort()) { | ||
return false; | ||
} | ||
Comment on lines
+456
to
+459
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we have a unit test for this if block? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The tests test hostname mismatch and port mismatch but not missing host or missing port. Like "127.0.0.0" or ":8080" |
||
InetAddress listenerIp = InetAddresses.forString(listenerAddressHnP.getHost()); | ||
InetAddress ldsIp = InetAddresses.forString(ldsAddressHnP.getHost()); | ||
return listenerIp.equals(ldsIp); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you get problems with the previous way? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, there were no problems here but I think if port isn't available or ports are not same then there's no point of parsing HostAndPort into InetAddress |
||
|
||
@Override | ||
public void onResourceDoesNotExist(final String resourceName) { | ||
if (stopped) { | ||
|
@@ -440,7 +470,7 @@ public void onResourceDoesNotExist(final String resourceName) { | |
StatusException statusException = Status.UNAVAILABLE.withDescription( | ||
String.format("Listener %s unavailable, xDS node ID: %s", resourceName, | ||
xdsClient.getBootstrapInfo().node().getId())).asException(); | ||
handleConfigNotFound(statusException); | ||
handleConfigNotFoundOrMismatch(statusException); | ||
} | ||
|
||
@Override | ||
|
@@ -673,7 +703,7 @@ public <ReqT, RespT> Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, | |
}; | ||
} | ||
|
||
private void handleConfigNotFound(StatusException exception) { | ||
private void handleConfigNotFoundOrMismatch(StatusException exception) { | ||
cleanUpRouteDiscoveryStates(); | ||
shutdownActiveFilters(); | ||
List<SslContextProviderSupplier> toRelease = getSuppliersInUse(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add unit test in GrpcXdsClientImplDataTest.