summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java1
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/search/RpcResourcePoolComponent.java31
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/search/test/SearchClusterTest.java40
-rwxr-xr-xconfig-proxy/src/main/sh/vespa-config-ctl.sh3
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/Dispatcher.java11
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcInvokerFactory.java9
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcResourcePool.java13
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcSearchInvoker.java1
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/searchcluster/SearchCluster.java7
-rw-r--r--container-search/src/test/java/com/yahoo/prelude/cluster/ClusterSearcherTestCase.java7
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/Roles.java1
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java5
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Role.java5
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java3
-rw-r--r--controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/user/RolesTest.java2
-rw-r--r--controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/role/RoleTest.java23
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/AthenzFacade.java4
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilter.java3
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiHandler.java5
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilterTest.java6
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java10
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiTest.java2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/user/responses/user-without-applications.json3
-rw-r--r--fbench/src/httpclient/httpclient.cpp4
-rw-r--r--fnet/src/tests/connect/connect_test.cpp6
-rw-r--r--fnet/src/vespa/fnet/connection.cpp5
-rw-r--r--fnet/src/vespa/fnet/transport.cpp10
-rw-r--r--fnet/src/vespa/fnet/transport.h18
-rwxr-xr-xlogserver/bin/logserver-start.sh2
-rw-r--r--metrics-proxy/src/main/java/ai/vespa/metricsproxy/core/MetricsManager.java11
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java20
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerList.java2
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/AclProvisioningTest.java29
-rw-r--r--storage/src/tests/frameworkimpl/status/statustest.cpp2
-rw-r--r--vbench/src/vbench/core/socket.cpp3
-rw-r--r--vbench/src/vbench/core/socket.h2
-rw-r--r--vespalib/src/tests/net/crypto_socket/crypto_socket_test.cpp11
-rw-r--r--vespalib/src/tests/net/socket_spec/socket_spec_test.cpp4
-rw-r--r--vespalib/src/tests/net/sync_crypto_socket/sync_crypto_socket_test.cpp11
-rw-r--r--vespalib/src/tests/portal/portal_test.cpp11
-rw-r--r--vespalib/src/vespa/vespalib/net/crypto_engine.cpp21
-rw-r--r--vespalib/src/vespa/vespalib/net/crypto_engine.h11
-rw-r--r--vespalib/src/vespa/vespalib/net/socket_spec.cpp2
-rw-r--r--vespalib/src/vespa/vespalib/net/socket_spec.h1
-rw-r--r--vespalib/src/vespa/vespalib/net/sync_crypto_socket.cpp43
-rw-r--r--vespalib/src/vespa/vespalib/net/sync_crypto_socket.h7
-rw-r--r--vespalib/src/vespa/vespalib/net/tls/auto_reloading_tls_crypto_engine.cpp17
-rw-r--r--vespalib/src/vespa/vespalib/net/tls/auto_reloading_tls_crypto_engine.h6
-rw-r--r--vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_engine.cpp16
-rw-r--r--vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_engine.h3
-rw-r--r--vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_socket.cpp2
-rw-r--r--vespalib/src/vespa/vespalib/net/tls/tls_crypto_engine.cpp12
-rw-r--r--vespalib/src/vespa/vespalib/net/tls/tls_crypto_engine.h13
-rw-r--r--vespalib/src/vespa/vespalib/portal/portal.cpp2
-rw-r--r--vespalib/src/vespa/vespalib/test/make_tls_options_for_testing.cpp2
-rw-r--r--vespalib/src/vespa/vespalib/test/make_tls_options_for_testing.h8
56 files changed, 368 insertions, 144 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java b/config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java
index e19d81e7fb2..77916921fe4 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java
@@ -59,6 +59,7 @@ public class ContainerSearch extends ContainerSubsystem<SearchChains>
for (AbstractSearchCluster searchCluster : searchClusters) {
if ( ! ( searchCluster instanceof IndexedSearchCluster)) continue;
owningCluster.addComponent(new DispatcherComponent((IndexedSearchCluster)searchCluster));
+ owningCluster.addComponent(new RpcResourcePoolComponent((IndexedSearchCluster)searchCluster));
}
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/search/RpcResourcePoolComponent.java b/config-model/src/main/java/com/yahoo/vespa/model/container/search/RpcResourcePoolComponent.java
new file mode 100644
index 00000000000..0291da611e8
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/search/RpcResourcePoolComponent.java
@@ -0,0 +1,31 @@
+// Copyright 2020 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.model.container.search;
+
+import com.yahoo.osgi.provider.model.ComponentModel;
+import com.yahoo.vespa.config.search.DispatchConfig;
+import com.yahoo.vespa.model.container.component.Component;
+import com.yahoo.vespa.model.container.xml.BundleMapper;
+import com.yahoo.vespa.model.search.IndexedSearchCluster;
+
+public class RpcResourcePoolComponent extends Component<RpcResourcePoolComponent, ComponentModel>
+ implements DispatchConfig.Producer {
+ private final IndexedSearchCluster indexedSearchCluster;
+
+ public RpcResourcePoolComponent(IndexedSearchCluster indexedSearchCluster) {
+ super(toComponentModel(indexedSearchCluster));
+ this.indexedSearchCluster = indexedSearchCluster;
+ }
+
+ @Override
+ public void getConfig(DispatchConfig.Builder builder) {
+ indexedSearchCluster.getConfig(builder);
+ }
+
+ private static ComponentModel toComponentModel(IndexedSearchCluster indexedSearchCluster) {
+ String componentId = "rpcresourcepool." + indexedSearchCluster.getClusterName(); // used by Dispatcher
+ return new ComponentModel(componentId,
+ "com.yahoo.search.dispatch.rpc.RpcResourcePool",
+ BundleMapper.searchAndDocprocBundle,
+ null);
+ }
+}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/search/test/SearchClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/search/test/SearchClusterTest.java
index 1c4e005cb67..c5bf5153369 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/search/test/SearchClusterTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/search/test/SearchClusterTest.java
@@ -18,7 +18,6 @@ import com.yahoo.vespa.model.VespaModel;
import com.yahoo.vespa.model.container.ContainerCluster;
import com.yahoo.vespa.model.container.component.Component;
import com.yahoo.vespa.model.search.AbstractSearchCluster;
-import com.yahoo.vespa.model.search.SearchCluster;
import com.yahoo.vespa.model.test.utils.ApplicationPackageUtils;
import com.yahoo.vespa.model.test.utils.VespaModelCreatorWithMockPkg;
import org.junit.Test;
@@ -160,23 +159,28 @@ public class SearchClusterTest {
AbstractSearchCluster searchCluster2 = model.getSearchClusters().get(xbulkIndex);
assertEquals("xbulk", searchCluster2.getClusterName());
- Component<?,?> normalDispatcher = (Component<?, ?>)containerCluster1.getComponentsMap().get(new ComponentId("dispatcher.normal"));
- assertNotNull(normalDispatcher);
- assertEquals("dispatcher.normal", normalDispatcher.getComponentId().stringValue());
- assertEquals("com.yahoo.search.dispatch.Dispatcher", normalDispatcher.getClassId().stringValue());
- assertEquals("j1/component/dispatcher.normal", normalDispatcher.getConfigId());
- DispatchConfig.Builder normalDispatchConfigBuilder = new DispatchConfig.Builder();
- model.getConfig(normalDispatchConfigBuilder, "j1/component/dispatcher.normal");
- assertEquals("node2host", normalDispatchConfigBuilder.build().node(0).host());
-
- Component<?,?> xbulkDispatcher = (Component<?, ?>)containerCluster1.getComponentsMap().get(new ComponentId("dispatcher.xbulk"));
- assertNotNull(xbulkDispatcher);
- assertEquals("dispatcher.xbulk", xbulkDispatcher.getComponentId().stringValue());
- assertEquals("com.yahoo.search.dispatch.Dispatcher", xbulkDispatcher.getClassId().stringValue());
- assertEquals("j1/component/dispatcher.xbulk", xbulkDispatcher.getConfigId());
- DispatchConfig.Builder xbulkDispatchConfigBuilder = new DispatchConfig.Builder();
- model.getConfig(xbulkDispatchConfigBuilder, "j1/component/dispatcher.xbulk");
- assertEquals("node0host", xbulkDispatchConfigBuilder.build().node(0).host());
+ verifyDispatch(model, containerCluster1, "normal", "node2host");
+ verifyDispatch(model, containerCluster1, "xbulk", "node0host");
+ }
+
+ private void verifyDispatch(VespaModel model, ContainerCluster containerCluster, String cluster, String host) {
+ Component<?,?> dispatcher = (Component<?, ?>)containerCluster.getComponentsMap().get(new ComponentId("dispatcher." + cluster));
+ assertNotNull(dispatcher);
+ assertEquals("dispatcher." + cluster, dispatcher.getComponentId().stringValue());
+ assertEquals("com.yahoo.search.dispatch.Dispatcher", dispatcher.getClassId().stringValue());
+ assertEquals("j1/component/dispatcher." + cluster, dispatcher.getConfigId());
+ DispatchConfig.Builder dispatchConfigBuilder = new DispatchConfig.Builder();
+ model.getConfig(dispatchConfigBuilder, "j1/component/dispatcher." + cluster);
+ assertEquals(host, dispatchConfigBuilder.build().node(0).host());
+
+ Component<?,?> rpcResourcePool = (Component<?, ?>)containerCluster.getComponentsMap().get(new ComponentId("rpcresourcepool." + cluster));
+ assertNotNull(dispatcher);
+ assertEquals("rpcresourcepool." + cluster, rpcResourcePool.getComponentId().stringValue());
+ assertEquals("com.yahoo.search.dispatch.rpc.RpcResourcePool", rpcResourcePool.getClassId().stringValue());
+ assertEquals("j1/component/rpcresourcepool."+cluster, rpcResourcePool.getConfigId());
+ DispatchConfig.Builder rpcResourcePoolDispatchConfigBuilder = new DispatchConfig.Builder();
+ model.getConfig(rpcResourcePoolDispatchConfigBuilder, "j1/component/rpcresourcepool." + cluster);
+ assertEquals(host, rpcResourcePoolDispatchConfigBuilder.build().node(0).host());
}
}
diff --git a/config-proxy/src/main/sh/vespa-config-ctl.sh b/config-proxy/src/main/sh/vespa-config-ctl.sh
index a17f0abed92..3998d4f69d6 100755
--- a/config-proxy/src/main/sh/vespa-config-ctl.sh
+++ b/config-proxy/src/main/sh/vespa-config-ctl.sh
@@ -113,7 +113,7 @@ case $1 in
if [ "$userargs" == "" ]; then
userargs=$services__jvmargs_configproxy
fi
- jvmopts="-Xms32M -Xmx256M -XX:ThreadStackSize=256 -XX:MaxJavaStackTraceDepth=1000000"
+ jvmopts="-Xms32M -Xmx256M -XX:CompressedClassSpaceSize=32m -XX:MaxDirectMemorySize=32m -XX:ThreadStackSize=256 -XX:MaxJavaStackTraceDepth=1000"
VESPA_SERVICE_NAME=configproxy
export VESPA_SERVICE_NAME
@@ -122,6 +122,7 @@ case $1 in
java ${jvmopts} \
-XX:+ExitOnOutOfMemoryError $(getJavaOptionsIPV46) \
-Dproxyconfigsources="${configsources}" ${userargs} \
+ -XX:ActiveProcessorCount=2 \
-cp $cp com.yahoo.vespa.config.proxy.ProxyServer 19090
echo "Waiting for config proxy to start"
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/Dispatcher.java b/container-search/src/main/java/com/yahoo/search/dispatch/Dispatcher.java
index 6ef41eefd12..abe6fffba39 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/Dispatcher.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/Dispatcher.java
@@ -83,18 +83,11 @@ public class Dispatcher extends AbstractComponent {
public static QueryProfileType getArgumentType() { return argumentType; }
@Inject
- public Dispatcher(ComponentId clusterId,
+ public Dispatcher(RpcResourcePool resourcePool,
+ ComponentId clusterId,
DispatchConfig dispatchConfig,
VipStatus vipStatus,
Metric metric) {
- this(new RpcResourcePool(dispatchConfig), clusterId, dispatchConfig, vipStatus, metric);
- }
-
- private Dispatcher(RpcResourcePool resourcePool,
- ComponentId clusterId,
- DispatchConfig dispatchConfig,
- VipStatus vipStatus,
- Metric metric) {
this(resourcePool, new SearchCluster(clusterId.stringValue(), dispatchConfig,
vipStatus, new RpcPingFactory(resourcePool)),
dispatchConfig, metric);
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcInvokerFactory.java b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcInvokerFactory.java
index a45ec59c3ee..74bc9e8bfbb 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcInvokerFactory.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcInvokerFactory.java
@@ -1,25 +1,19 @@
// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.search.dispatch.rpc;
-import com.yahoo.prelude.Pong;
import com.yahoo.prelude.fastsearch.DocumentDatabase;
import com.yahoo.prelude.fastsearch.VespaBackEndSearcher;
import com.yahoo.processing.request.CompoundName;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
-import com.yahoo.search.cluster.ClusterMonitor;
import com.yahoo.search.dispatch.Dispatcher;
import com.yahoo.search.dispatch.FillInvoker;
import com.yahoo.search.dispatch.InvokerFactory;
import com.yahoo.search.dispatch.SearchInvoker;
import com.yahoo.search.dispatch.searchcluster.Node;
-import com.yahoo.search.dispatch.searchcluster.PingFactory;
-import com.yahoo.search.dispatch.searchcluster.Pinger;
-import com.yahoo.search.dispatch.searchcluster.PongHandler;
import com.yahoo.search.dispatch.searchcluster.SearchCluster;
import java.util.Optional;
-import java.util.concurrent.Callable;
/**
* @author ollivir
@@ -62,7 +56,4 @@ public class RpcInvokerFactory extends InvokerFactory {
return new RpcFillInvoker(rpcResourcePool, documentDb);
}
- public void release() {
- rpcResourcePool.release();
- }
}
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcResourcePool.java b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcResourcePool.java
index ca2a0c9bfb0..065489ef9a0 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcResourcePool.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcResourcePool.java
@@ -2,6 +2,9 @@
package com.yahoo.search.dispatch.rpc;
import com.google.common.collect.ImmutableMap;
+import com.google.inject.Inject;
+import com.yahoo.component.AbstractComponent;
+import com.yahoo.component.ComponentId;
import com.yahoo.compress.CompressionType;
import com.yahoo.compress.Compressor;
import com.yahoo.compress.Compressor.Compression;
@@ -23,7 +26,7 @@ import java.util.Random;
*
* @author ollivir
*/
-public class RpcResourcePool {
+public class RpcResourcePool extends AbstractComponent {
/** The compression method which will be used with rpc dispatch. "lz4" (default) and "none" is supported. */
public final static CompoundName dispatchCompression = new CompoundName("dispatch.compression");
@@ -33,13 +36,15 @@ public class RpcResourcePool {
/** Connections to the search nodes this talks to, indexed by node id ("partid") */
private final ImmutableMap<Integer, NodeConnectionPool> nodeConnectionPools;
- public RpcResourcePool(Map<Integer, NodeConnection> nodeConnections) {
+ RpcResourcePool(Map<Integer, NodeConnection> nodeConnections) {
var builder = new ImmutableMap.Builder<Integer, NodeConnectionPool>();
nodeConnections.forEach((key, connection) -> builder.put(key, new NodeConnectionPool(Collections.singletonList(connection))));
this.nodeConnectionPools = builder.build();
}
+ @Inject
public RpcResourcePool(DispatchConfig dispatchConfig) {
+ super();
var client = new RpcClient(dispatchConfig.numJrtTransportThreads());
// Create rpc node connection pools indexed by the node distribution key
@@ -73,7 +78,9 @@ public class RpcResourcePool {
}
}
- public void release() {
+ @Override
+ public void deconstruct() {
+ super.deconstruct();
nodeConnectionPools.values().forEach(NodeConnectionPool::release);
}
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcSearchInvoker.java b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcSearchInvoker.java
index 07d8439ff46..76240e55c98 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcSearchInvoker.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcSearchInvoker.java
@@ -5,7 +5,6 @@ import com.yahoo.compress.CompressionType;
import com.yahoo.compress.Compressor;
import com.yahoo.prelude.fastsearch.VespaBackEndSearcher;
import com.yahoo.search.Query;
-import com.yahoo.search.Result;
import com.yahoo.search.dispatch.InvokerResult;
import com.yahoo.search.dispatch.SearchInvoker;
import com.yahoo.search.dispatch.rpc.Client.ProtobufResponse;
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/searchcluster/SearchCluster.java b/container-search/src/main/java/com/yahoo/search/dispatch/searchcluster/SearchCluster.java
index cc705668992..59b73df0ef3 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/searchcluster/SearchCluster.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/searchcluster/SearchCluster.java
@@ -79,6 +79,13 @@ public class SearchCluster implements NodeManager<Node> {
this.localCorpusDispatchTarget = findLocalCorpusDispatchTarget(HostName.getLocalhost(), nodesByHost, groups);
}
+
+ /* Testing only */
+ public SearchCluster(String clusterId, DispatchConfig dispatchConfig,
+ VipStatus vipStatus, PingFactory pingFactory) {
+ this(clusterId, dispatchConfig, 1, vipStatus, pingFactory);
+ }
+
public void addMonitoring(ClusterMonitor clusterMonitor) {
for (var group : orderedGroups) {
for (var node : group.nodes())
diff --git a/container-search/src/test/java/com/yahoo/prelude/cluster/ClusterSearcherTestCase.java b/container-search/src/test/java/com/yahoo/prelude/cluster/ClusterSearcherTestCase.java
index fb57f5eccd6..5382999f96a 100644
--- a/container-search/src/test/java/com/yahoo/prelude/cluster/ClusterSearcherTestCase.java
+++ b/container-search/src/test/java/com/yahoo/prelude/cluster/ClusterSearcherTestCase.java
@@ -21,6 +21,7 @@ import com.yahoo.search.Query;
import com.yahoo.search.Result;
import com.yahoo.search.config.ClusterConfig;
import com.yahoo.search.dispatch.Dispatcher;
+import com.yahoo.search.dispatch.rpc.RpcResourcePool;
import com.yahoo.search.result.Hit;
import com.yahoo.search.searchchain.Execution;
import com.yahoo.vespa.config.search.DispatchConfig;
@@ -513,8 +514,10 @@ public class ClusterSearcherTestCase {
DocumentdbInfoConfig.Builder documentDbConfig = new DocumentdbInfoConfig.Builder();
documentDbConfig.documentdb(new DocumentdbInfoConfig.Documentdb.Builder().name("type1"));
- Dispatcher dispatcher = new Dispatcher(new ComponentId("test-id"),
- new DispatchConfig.Builder().build(),
+ DispatchConfig dispatchConfig = new DispatchConfig.Builder().build();
+ Dispatcher dispatcher = new Dispatcher(new RpcResourcePool(dispatchConfig),
+ ComponentId.createAnonymousComponentId("test-id"),
+ dispatchConfig,
vipStatus,
new MockMetric());
ComponentRegistry<Dispatcher> dispatchers = new ComponentRegistry<>();
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/Roles.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/Roles.java
index 77bd589f23b..f5f3ebe8f35 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/Roles.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/Roles.java
@@ -35,6 +35,7 @@ public class Roles {
public static Role toRole(String value) {
String[] parts = value.split("\\.");
if (parts.length == 1 && parts[0].equals("hostedOperator")) return Role.hostedOperator();
+ if (parts.length == 1 && parts[0].equals("hostedSupporter")) return Role.hostedSupporter();
if (parts.length == 2) return toRole(TenantName.from(parts[0]), parts[1]);
if (parts.length == 3) return toRole(TenantName.from(parts[0]), ApplicationName.from(parts[1]), parts[2]);
throw new IllegalArgumentException("Malformed or illegal role value '" + value + "'.");
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java
index e27fb0fbf27..0e8e3a13f9f 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java
@@ -23,6 +23,11 @@ enum Policy {
.on(PathGroup.all())
.in(SystemName.all())),
+ /** Full access to everything. */
+ supporter(Privilege.grant(Action.read)
+ .on(PathGroup.all())
+ .in(SystemName.all())),
+
/** Full access to user management for a tenant in select systems. */
tenantManager(Privilege.grant(Action.all())
.on(PathGroup.tenantUsers)
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Role.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Role.java
index b53cf9162e7..263e3284dbd 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Role.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Role.java
@@ -28,6 +28,11 @@ public abstract class Role {
return new UnboundRole(RoleDefinition.hostedOperator);
}
+ /** Returns a {@link RoleDefinition#hostedSupporter} for the current system. */
+ public static UnboundRole hostedSupporter() {
+ return new UnboundRole(RoleDefinition.hostedSupporter);
+ }
+
/** Returns a {@link RoleDefinition#everyone} for the current system. */
public static UnboundRole everyone() {
return new UnboundRole(RoleDefinition.everyone);
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java
index 58d69512feb..848866f7c33 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java
@@ -21,6 +21,9 @@ public enum RoleDefinition {
/** Deus ex machina. */
hostedOperator(Policy.operator),
+ /** Machina autem exspiravit. */
+ hostedSupporter(Policy.supporter),
+
/** Base role which every user is part of. */
everyone(Policy.classifiedRead,
Policy.classifiedApiRead,
diff --git a/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/user/RolesTest.java b/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/user/RolesTest.java
index cfb5462e50a..22baedd16b4 100644
--- a/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/user/RolesTest.java
+++ b/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/user/RolesTest.java
@@ -27,6 +27,8 @@ public class RolesTest {
assertEquals(Role.hostedOperator(),
Roles.toRole("hostedOperator"));
+ assertEquals(Role.hostedSupporter(),
+ Roles.toRole("hostedSupporter"));
assertEquals(Role.tenantOperator(tenant),
Roles.toRole("my-tenant.tenantOperator"));
assertEquals(Role.applicationReader(tenant, application),
diff --git a/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/role/RoleTest.java b/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/role/RoleTest.java
index d153e218640..da2f64f2893 100644
--- a/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/role/RoleTest.java
+++ b/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/role/RoleTest.java
@@ -33,6 +33,27 @@ public class RoleTest {
}
@Test
+ public void supporter_membership() {
+ Role role = Role.hostedSupporter();
+
+ // No create update or delete
+ assertFalse(mainEnforcer.allows(role, Action.create, URI.create("/not/explicitly/defined")));
+ assertFalse(mainEnforcer.allows(role, Action.create, URI.create("/controller/v1/foo")));
+ assertFalse(mainEnforcer.allows(role, Action.update, URI.create("/os/v1/bar")));
+ assertFalse(mainEnforcer.allows(role, Action.update, URI.create("/application/v4/tenant/t1/application/a1")));
+ assertFalse(mainEnforcer.allows(role, Action.update, URI.create("/application/v4/tenant/t2/application/a2")));
+ assertFalse(mainEnforcer.allows(role, Action.delete, URI.create("/application/v4/tenant/t8/application/a6/instance/i1/environment/dev/region/r1")));
+
+ // But reads is ok (but still only for valid paths)
+ assertFalse(mainEnforcer.allows(role, Action.read, URI.create("/not/explicitly/defined")));
+ assertTrue(mainEnforcer.allows(role, Action.read, URI.create("/controller/v1/foo")));
+ assertTrue(mainEnforcer.allows(role, Action.read, URI.create("/os/v1/bar")));
+ assertTrue(mainEnforcer.allows(role, Action.read, URI.create("/application/v4/tenant/t1/application/a1")));
+ assertTrue(mainEnforcer.allows(role, Action.read, URI.create("/application/v4/tenant/t2/application/a2")));
+ assertFalse(mainEnforcer.allows(role, Action.delete, URI.create("/application/v4/tenant/t8/application/a6/instance/i1/environment/dev/region/r1")));
+ }
+
+ @Test
public void tenant_membership() {
Role role = Role.athenzTenantAdmin(TenantName.from("t1"));
assertFalse(mainEnforcer.allows(role, Action.create, URI.create("/not/explicitly/defined")));
@@ -133,12 +154,14 @@ public class RoleTest {
Action action = Action.update;
assertTrue(mainEnforcer.allows(Role.systemFlagsDeployer(), action, deployUri));
assertTrue(mainEnforcer.allows(Role.hostedOperator(), action, deployUri));
+ assertFalse(mainEnforcer.allows(Role.hostedSupporter(), action, deployUri));
assertFalse(mainEnforcer.allows(Role.systemFlagsDryrunner(), action, deployUri));
assertFalse(mainEnforcer.allows(Role.everyone(), action, deployUri));
URI dryrunUri = URI.create("/system-flags/v1/dryrun");
assertTrue(mainEnforcer.allows(Role.systemFlagsDeployer(), action, dryrunUri));
assertTrue(mainEnforcer.allows(Role.hostedOperator(), action, dryrunUri));
+ assertFalse(mainEnforcer.allows(Role.hostedSupporter(), action, dryrunUri));
assertTrue(mainEnforcer.allows(Role.systemFlagsDryrunner(), action, dryrunUri));
assertFalse(mainEnforcer.allows(Role.everyone(), action, dryrunUri));
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/AthenzFacade.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/AthenzFacade.java
index 7ace62ab44d..628d7f48c85 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/AthenzFacade.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/AthenzFacade.java
@@ -215,6 +215,10 @@ public class AthenzFacade implements AccessControl {
return hasAccess("modify", service.getDomain().getName() + ":hosted-vespa", identity);
}
+ public boolean hasHostedSupporterAccess(AthenzIdentity identity) {
+ return hasAccess("read", service.getDomain().getName() + ":hosted-vespa", identity);
+ }
+
public boolean canLaunch(AthenzIdentity principal, AthenzService service) {
return hasAccess("launch", service.getDomain().getName() + ":service."+service.getName(), principal);
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilter.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilter.java
index 1aaecb58a8d..ba974521278 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilter.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilter.java
@@ -87,6 +87,9 @@ public class AthenzRoleFilter extends JsonSecurityRequestFilterBase {
if (athenz.hasHostedOperatorAccess(identity))
roleMemberships.add(Role.hostedOperator());
+ if (athenz.hasHostedSupporterAccess(identity))
+ roleMemberships.add(Role.hostedSupporter());
+
// Add all tenants that are accessible for this request
athenz.accessibleTenants(tenants.asList(), new Credentials(principal))
.forEach(accessibleTenant -> roleMemberships.add(Role.athenzTenantAdmin(accessibleTenant.name())));
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiHandler.java
index d9ffe8a251c..847a6c96a53 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiHandler.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiHandler.java
@@ -134,10 +134,11 @@ public class UserApiHandler extends LoggingRequestHandler {
// List of operator roles, currently only one available, but possible to extend
List<Role> operatorRoles = roles.stream()
- .filter(role -> role.definition().equals(RoleDefinition.hostedOperator))
+ .filter(role -> role.definition().equals(RoleDefinition.hostedOperator) ||
+ role.definition().equals(RoleDefinition.hostedSupporter))
+ .sorted(Comparator.comparing(Role::definition))
.collect(Collectors.toList());
-
Slime slime = new Slime();
Cursor root = slime.setObject();
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilterTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilterTest.java
index 82b97a5b144..bef27f7a2f5 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilterTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilterTest.java
@@ -73,13 +73,13 @@ public class AthenzRoleFilterTest {
public void testTranslations() {
// Hosted operators are always members of the hostedOperator role.
- assertEquals(Set.of(Role.hostedOperator(), Role.systemFlagsDeployer(), Role.systemFlagsDryrunner()),
+ assertEquals(Set.of(Role.hostedOperator(), Role.systemFlagsDeployer(), Role.systemFlagsDryrunner(), Role.hostedSupporter()),
filter.roles(HOSTED_OPERATOR, NO_CONTEXT_PATH));
- assertEquals(Set.of(Role.hostedOperator(), Role.systemFlagsDeployer(), Role.systemFlagsDryrunner()),
+ assertEquals(Set.of(Role.hostedOperator(), Role.systemFlagsDeployer(), Role.systemFlagsDryrunner(), Role.hostedSupporter()),
filter.roles(HOSTED_OPERATOR, TENANT_CONTEXT_PATH));
- assertEquals(Set.of(Role.hostedOperator(), Role.systemFlagsDeployer(), Role.systemFlagsDryrunner()),
+ assertEquals(Set.of(Role.hostedOperator(), Role.systemFlagsDeployer(), Role.systemFlagsDryrunner(), Role.hostedSupporter()),
filter.roles(HOSTED_OPERATOR, APPLICATION_CONTEXT_PATH));
// Tenant admins are members of the athenzTenantAdmin role within their tenant subtree.
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java
index a5520b42459..c95691fc120 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java
@@ -43,6 +43,16 @@ public class ControllerAuthorizationFilterTest {
}
@Test
+ public void supporter() {
+ ControllerTester tester = new ControllerTester();
+ SecurityContext securityContext = new SecurityContext(() -> "operator", Set.of(Role.hostedSupporter()));
+ ControllerAuthorizationFilter filter = createFilter(tester);
+
+ assertIsForbidden(invokeFilter(filter, createRequest(Method.POST, "/zone/v2/path", securityContext)));
+ assertIsAllowed(invokeFilter(filter, createRequest(Method.GET, "/zone/v1/path", securityContext)));
+ }
+
+ @Test
public void unprivileged() {
ControllerTester tester = new ControllerTester();
SecurityContext securityContext = new SecurityContext(() -> "user", Set.of(Role.everyone()));
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiTest.java
index d1dd50cfb4c..d70a09414bb 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiTest.java
@@ -203,7 +203,7 @@ public class UserApiTest extends ControllerContainerCloudTest {
public void userMetadataTest() {
ContainerTester tester = new ContainerTester(container, responseFiles);
ControllerTester controller = new ControllerTester(tester);
- Set<Role> operator = Set.of(Role.hostedOperator());
+ Set<Role> operator = Set.of(Role.hostedOperator(), Role.hostedSupporter());
User user = new User("dev@domail", "Joe Developer", "dev", null);
tester.assertResponse(request("/api/user/v1/user")
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/user/responses/user-without-applications.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/user/responses/user-without-applications.json
index 17489bb15d8..400fe8d4d9b 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/user/responses/user-without-applications.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/user/responses/user-without-applications.json
@@ -7,6 +7,7 @@
},
"tenants": {},
"operator": [
- "hostedOperator"
+ "hostedOperator",
+ "hostedSupporter"
]
}
diff --git a/fbench/src/httpclient/httpclient.cpp b/fbench/src/httpclient/httpclient.cpp
index 002d2770dcd..99134a6e297 100644
--- a/fbench/src/httpclient/httpclient.cpp
+++ b/fbench/src/httpclient/httpclient.cpp
@@ -1,5 +1,6 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "httpclient.h"
+#include <vespa/vespalib/net/socket_spec.h>
#include <cassert>
#include <cstring>
@@ -69,7 +70,8 @@ HTTPClient::connect_socket()
if (!handle.valid()) {
return false;
}
- _socket = vespalib::SyncCryptoSocket::create(*_engine, std::move(handle), false);
+ _socket = vespalib::SyncCryptoSocket::create_client(*_engine, std::move(handle),
+ vespalib::SocketSpec::from_host_port(_hostname, _port));
return bool(_socket);
}
diff --git a/fnet/src/tests/connect/connect_test.cpp b/fnet/src/tests/connect/connect_test.cpp
index b70b3fa8b01..d94b6759077 100644
--- a/fnet/src/tests/connect/connect_test.cpp
+++ b/fnet/src/tests/connect/connect_test.cpp
@@ -65,7 +65,11 @@ struct BlockingCryptoEngine : public CryptoEngine {
Gate handshake_work_enter;
Gate handshake_work_exit;
Gate handshake_socket_deleted;
- CryptoSocket::UP create_crypto_socket(SocketHandle socket, bool) override {
+ CryptoSocket::UP create_client_crypto_socket(SocketHandle socket, const SocketSpec &) override {
+ return std::make_unique<BlockingCryptoSocket>(std::move(socket),
+ handshake_work_enter, handshake_work_exit, handshake_socket_deleted);
+ }
+ CryptoSocket::UP create_server_crypto_socket(SocketHandle socket) override {
return std::make_unique<BlockingCryptoSocket>(std::move(socket),
handshake_work_enter, handshake_work_exit, handshake_socket_deleted);
}
diff --git a/fnet/src/vespa/fnet/connection.cpp b/fnet/src/vespa/fnet/connection.cpp
index 5f7adb32af0..c5afd627a5a 100644
--- a/fnet/src/vespa/fnet/connection.cpp
+++ b/fnet/src/vespa/fnet/connection.cpp
@@ -9,6 +9,7 @@
#include "config.h"
#include "transport_thread.h"
#include "transport.h"
+#include <vespa/vespalib/net/socket_spec.h>
#include <vespa/log/log.h>
LOG_SETUP(".fnet");
@@ -472,7 +473,7 @@ FNET_Connection::FNET_Connection(FNET_TransportThread *owner,
_streamer(streamer),
_serverAdapter(serverAdapter),
_adminChannel(nullptr),
- _socket(owner->owner().create_crypto_socket(std::move(socket), true)),
+ _socket(owner->owner().create_server_crypto_socket(std::move(socket))),
_resolve_handler(nullptr),
_context(),
_state(FNET_CONNECTING),
@@ -579,7 +580,7 @@ FNET_Connection::handle_add_event()
{
if (_resolve_handler) {
auto tweak = [this](vespalib::SocketHandle &handle) { return Owner()->tune(handle); };
- _socket = Owner()->owner().create_crypto_socket(_resolve_handler->address.connect(tweak), false);
+ _socket = Owner()->owner().create_client_crypto_socket(_resolve_handler->address.connect(tweak), vespalib::SocketSpec(GetSpec()));
_ioc_socket_fd = _socket->get_fd();
_resolve_handler.reset();
}
diff --git a/fnet/src/vespa/fnet/transport.cpp b/fnet/src/vespa/fnet/transport.cpp
index 28e645d9e03..d3b52969c8c 100644
--- a/fnet/src/vespa/fnet/transport.cpp
+++ b/fnet/src/vespa/fnet/transport.cpp
@@ -54,9 +54,15 @@ FNET_Transport::resolve_async(const vespalib::string &spec,
}
vespalib::CryptoSocket::UP
-FNET_Transport::create_crypto_socket(vespalib::SocketHandle socket, bool is_server)
+FNET_Transport::create_client_crypto_socket(vespalib::SocketHandle socket, const vespalib::SocketSpec &spec)
{
- return _crypto_engine->create_crypto_socket(std::move(socket), is_server);
+ return _crypto_engine->create_client_crypto_socket(std::move(socket), spec);
+}
+
+vespalib::CryptoSocket::UP
+FNET_Transport::create_server_crypto_socket(vespalib::SocketHandle socket)
+{
+ return _crypto_engine->create_server_crypto_socket(std::move(socket));
}
FNET_TransportThread *
diff --git a/fnet/src/vespa/fnet/transport.h b/fnet/src/vespa/fnet/transport.h
index 8d1ba48c1b0..02ef22c7fb6 100644
--- a/fnet/src/vespa/fnet/transport.h
+++ b/fnet/src/vespa/fnet/transport.h
@@ -79,17 +79,25 @@ public:
vespalib::AsyncResolver::ResultHandler::WP result_handler);
/**
- * Wrap a plain socket endpoint in a CryptoSocket. The
+ * Wrap a plain socket endpoint (client side) in a CryptoSocket. The
* implementation will be determined by the CryptoEngine used by
* this Transport.
*
* @return socket abstraction able to perform encryption and decryption
* @param socket low-level socket
- * @param is_server which end of the connection the socket
- * represents. This is needed to support
- * asymmetrical handshaking.
+ * @param spec who we are connecting to
**/
- vespalib::CryptoSocket::UP create_crypto_socket(vespalib::SocketHandle socket, bool is_server);
+ vespalib::CryptoSocket::UP create_client_crypto_socket(vespalib::SocketHandle socket, const vespalib::SocketSpec &spec);
+
+ /**
+ * Wrap a plain socket endpoint (server side) in a CryptoSocket. The
+ * implementation will be determined by the CryptoEngine used by
+ * this Transport.
+ *
+ * @return socket abstraction able to perform encryption and decryption
+ * @param socket low-level socket
+ **/
+ vespalib::CryptoSocket::UP create_server_crypto_socket(vespalib::SocketHandle socket);
/**
* Select one of the underlying transport threads. The selection
diff --git a/logserver/bin/logserver-start.sh b/logserver/bin/logserver-start.sh
index 9f55e218140..913cdb78327 100755
--- a/logserver/bin/logserver-start.sh
+++ b/logserver/bin/logserver-start.sh
@@ -78,7 +78,7 @@ ROOT=${VESPA_HOME%/}
export ROOT
cd $ROOT || { echo "Cannot cd to $ROOT" 1>&2; exit 1; }
-addopts="-server -Xms32m -Xmx256m -XX:MaxDirectMemorySize=76m -XX:MaxJavaStackTraceDepth=1000000"
+addopts="-server -Xms32m -Xmx256m -XX:CompressedClassSpaceSize=32m -XX:MaxDirectMemorySize=32m -XX:ThreadStackSize=256 -XX:MaxJavaStackTraceDepth=1000 -XX:ActiveProcessorCount=2"
oomopt="-XX:+ExitOnOutOfMemoryError"
diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/core/MetricsManager.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/core/MetricsManager.java
index 4c4015220bc..53a05ef88f0 100644
--- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/core/MetricsManager.java
+++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/core/MetricsManager.java
@@ -79,6 +79,16 @@ public class MetricsManager {
* @return Metrics for all matching services.
*/
public List<MetricsPacket> getMetrics(List<VespaService> services, Instant startTime) {
+ return getMetricsAsBuilders(services, startTime).stream()
+ .map(MetricsPacket.Builder::build)
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * Returns the metrics for the given services, in mutable state for further processing.
+ * NOTE: Use {@link #getMetrics(List, Instant)} instead, unless further processing of the metrics is necessary.
+ */
+ public List<MetricsPacket.Builder> getMetricsAsBuilders(List<VespaService> services, Instant startTime) {
if (services.isEmpty()) return Collections.emptyList();
log.log(DEBUG, () -> "Updating services prior to fetching metrics, number of services= " + services.size());
@@ -99,7 +109,6 @@ public class MetricsManager {
.map(builder -> builder.putDimensionsIfAbsent(getGlobalDimensions()))
.map(builder -> builder.putDimensionsIfAbsent(extraDimensions))
.map(builder -> adjustTimestamp(builder, startTime))
- .map(MetricsPacket.Builder::build)
.collect(Collectors.toList());
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java
index 48a53104f7f..4af68fa702c 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java
@@ -215,7 +215,7 @@ public class NodeRepository extends AbstractComponent {
/**
* Returns the ACL for the node (trusted nodes, networks and ports)
*/
- private NodeAcl getNodeAcl(Node node, NodeList candidates, LoadBalancerList loadBalancers) {
+ private NodeAcl getNodeAcl(Node node, NodeList candidates) {
Set<Node> trustedNodes = new TreeSet<>(Comparator.comparing(Node::hostname));
Set<Integer> trustedPorts = new LinkedHashSet<>();
Set<String> trustedNetworks = new LinkedHashSet<>();
@@ -232,10 +232,10 @@ public class NodeRepository extends AbstractComponent {
candidates.parentOf(node).ifPresent(trustedNodes::add);
node.allocation().ifPresent(allocation -> {
trustedNodes.addAll(candidates.owner(allocation.owner()).asList());
- loadBalancers.asList().stream()
- .map(LoadBalancer::instance)
- .map(LoadBalancerInstance::networks)
- .forEach(trustedNetworks::addAll);
+ loadBalancers(allocation.owner()).asList().stream()
+ .map(LoadBalancer::instance)
+ .map(LoadBalancerInstance::networks)
+ .forEach(trustedNetworks::addAll);
});
switch (node.type()) {
@@ -304,18 +304,12 @@ public class NodeRepository extends AbstractComponent {
*/
public List<NodeAcl> getNodeAcls(Node node, boolean children) {
NodeList candidates = list();
- LoadBalancerList loadBalancers;
- if (node.allocation().isPresent()) {
- loadBalancers = loadBalancers(node.allocation().get().owner());
- } else {
- loadBalancers = LoadBalancerList.EMPTY;
- }
if (children) {
return candidates.childrenOf(node).asList().stream()
- .map(childNode -> getNodeAcl(childNode, candidates, loadBalancers))
+ .map(childNode -> getNodeAcl(childNode, candidates))
.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
}
- return Collections.singletonList(getNodeAcl(node, candidates, loadBalancers));
+ return Collections.singletonList(getNodeAcl(node, candidates));
}
public NodeFlavors getAvailableFlavors() {
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerList.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerList.java
index 479fd328162..bad16bf7d12 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerList.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/lb/LoadBalancerList.java
@@ -15,8 +15,6 @@ import java.util.stream.Stream;
*/
public class LoadBalancerList implements Iterable<LoadBalancer> {
- public static LoadBalancerList EMPTY = new LoadBalancerList(List.of());
-
private final List<LoadBalancer> loadBalancers;
private LoadBalancerList(Collection<LoadBalancer> loadBalancers) {
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/AclProvisioningTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/AclProvisioningTest.java
index 92d066e5f16..8995897769c 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/AclProvisioningTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/AclProvisioningTest.java
@@ -164,12 +164,33 @@ public class AclProvisioningTest {
@Test
public void trusted_nodes_for_application_with_load_balancer() {
- // Populate repo
- tester.makeReadyNodes(10, nodeResources);
+ // Provision hosts and containers
+ var hosts = tester.makeReadyNodes(2, "default", NodeType.host);
+ tester.deployZoneApp();
+ for (var host : hosts) {
+ tester.makeReadyVirtualDockerNodes(2, new NodeResources(2, 8, 50, 1),
+ host.hostname());
+ }
- // Allocate 2 nodes
- List<Node> activeNodes = deploy(2);
+ // Deploy application
+ var application = tester.makeApplicationId();
+ List<Node> activeNodes = deploy(application, 2);
assertEquals(2, activeNodes.size());
+
+ // Load balancer is allocated to application
+ var loadBalancers = tester.nodeRepository().loadBalancers(application);
+ assertEquals(1, loadBalancers.asList().size());
+ var lbNetworks = loadBalancers.asList().get(0).instance().networks();
+ assertEquals(2, lbNetworks.size());
+
+ // ACL for nodes with allocation trust their respective load balancer networks, if any
+ for (var host : hosts) {
+ var acls = tester.nodeRepository().getNodeAcls(host, true);
+ assertEquals(2, acls.size());
+ assertEquals(Set.of(), acls.get(0).trustedNetworks());
+ assertEquals(application, acls.get(1).node().allocation().get().owner());
+ assertEquals(lbNetworks, acls.get(1).trustedNetworks());
+ }
}
@Test
diff --git a/storage/src/tests/frameworkimpl/status/statustest.cpp b/storage/src/tests/frameworkimpl/status/statustest.cpp
index 81d91e2f08a..7c259f00899 100644
--- a/storage/src/tests/frameworkimpl/status/statustest.cpp
+++ b/storage/src/tests/frameworkimpl/status/statustest.cpp
@@ -19,7 +19,7 @@ vespalib::string fetch(int port, const vespalib::string &path) {
auto crypto = vespalib::CryptoEngine::get_default();
auto socket = vespalib::SocketSpec::from_port(port).client_address().connect();
assert(socket.valid());
- auto conn = vespalib::SyncCryptoSocket::create(*crypto, std::move(socket), false);
+ auto conn = vespalib::SyncCryptoSocket::create_client(*crypto, std::move(socket), vespalib::SocketSpec::from_host_port("localhost", port));
vespalib::string http_req = vespalib::make_string("GET %s HTTP/1.1\r\n"
"Host: localhost:%d\r\n"
"\r\n", path.c_str(), port);
diff --git a/vbench/src/vbench/core/socket.cpp b/vbench/src/vbench/core/socket.cpp
index 822b96b2c07..0431b6889a8 100644
--- a/vbench/src/vbench/core/socket.cpp
+++ b/vbench/src/vbench/core/socket.cpp
@@ -29,7 +29,8 @@ Socket::Socket(SyncCryptoSocket::UP socket)
}
Socket::Socket(CryptoEngine &crypto, const string &host, int port)
- : _socket(SyncCryptoSocket::create(crypto, connect(host, port), false)),
+ : _socket(SyncCryptoSocket::create_client(crypto, connect(host, port),
+ vespalib::SocketSpec::from_host_port(host, port))),
_input(),
_output(),
_taint(),
diff --git a/vbench/src/vbench/core/socket.h b/vbench/src/vbench/core/socket.h
index 0e8848e8292..4b5721c0fb7 100644
--- a/vbench/src/vbench/core/socket.h
+++ b/vbench/src/vbench/core/socket.h
@@ -52,7 +52,7 @@ struct ServerSocket {
Stream::UP accept(CryptoEngine &crypto) {
vespalib::SocketHandle handle = server_socket.accept();
if (handle.valid()) {
- return std::make_unique<Socket>(SyncCryptoSocket::create(crypto, std::move(handle), true));
+ return std::make_unique<Socket>(SyncCryptoSocket::create_server(crypto, std::move(handle)));
} else {
return Stream::UP();
}
diff --git a/vespalib/src/tests/net/crypto_socket/crypto_socket_test.cpp b/vespalib/src/tests/net/crypto_socket/crypto_socket_test.cpp
index 62bad716597..e938e15f4e6 100644
--- a/vespalib/src/tests/net/crypto_socket/crypto_socket_test.cpp
+++ b/vespalib/src/tests/net/crypto_socket/crypto_socket_test.cpp
@@ -17,6 +17,7 @@
#include <fcntl.h>
using namespace vespalib;
+using namespace vespalib::test;
struct SocketPair {
SocketHandle client;
@@ -204,7 +205,9 @@ void verify_crypto_socket(SocketPair &sockets, CryptoEngine &engine, bool is_ser
SocketHandle &my_handle = is_server ? sockets.server : sockets.client;
my_handle.set_blocking(false);
SmartBuffer read_buffer(4096);
- CryptoSocket::UP my_socket = engine.create_crypto_socket(std::move(my_handle), is_server);
+ CryptoSocket::UP my_socket = is_server
+ ? engine.create_server_crypto_socket(std::move(my_handle))
+ : engine.create_client_crypto_socket(std::move(my_handle), local_spec);
TEST_DO(verify_handshake(*my_socket));
drain(*my_socket, read_buffer);
TEST_DO(verify_socket_io(*my_socket, read_buffer, is_server));
@@ -226,19 +229,19 @@ TEST_MT_FFF("require that encrypted async socket io works with XorCryptoEngine",
}
TEST_MT_FFF("require that encrypted async socket io works with TlsCryptoEngine",
- 2, SocketPair(), TlsCryptoEngine(vespalib::test::make_tls_options_for_testing()), TimeBomb(60))
+ 2, SocketPair(), TlsCryptoEngine(make_tls_options_for_testing()), TimeBomb(60))
{
TEST_DO(verify_crypto_socket(f1, f2, (thread_id == 0)));
}
TEST_MT_FFF("require that encrypted async socket io works with MaybeTlsCryptoEngine(true)",
- 2, SocketPair(), MaybeTlsCryptoEngine(std::make_shared<TlsCryptoEngine>(vespalib::test::make_tls_options_for_testing()), true), TimeBomb(60))
+ 2, SocketPair(), MaybeTlsCryptoEngine(std::make_shared<TlsCryptoEngine>(make_tls_options_for_testing()), true), TimeBomb(60))
{
TEST_DO(verify_crypto_socket(f1, f2, (thread_id == 0)));
}
TEST_MT_FFF("require that encrypted async socket io works with MaybeTlsCryptoEngine(false)",
- 2, SocketPair(), MaybeTlsCryptoEngine(std::make_shared<TlsCryptoEngine>(vespalib::test::make_tls_options_for_testing()), false), TimeBomb(60))
+ 2, SocketPair(), MaybeTlsCryptoEngine(std::make_shared<TlsCryptoEngine>(make_tls_options_for_testing()), false), TimeBomb(60))
{
TEST_DO(verify_crypto_socket(f1, f2, (thread_id == 0)));
}
diff --git a/vespalib/src/tests/net/socket_spec/socket_spec_test.cpp b/vespalib/src/tests/net/socket_spec/socket_spec_test.cpp
index 0c2b92bbb53..f2da6b70bf3 100644
--- a/vespalib/src/tests/net/socket_spec/socket_spec_test.cpp
+++ b/vespalib/src/tests/net/socket_spec/socket_spec_test.cpp
@@ -123,4 +123,8 @@ TEST("require that replace_host gives invalid spec when used with less than 2 ho
TEST_DO(verify_invalid(SocketSpec("ipc/name:my_socket").replace_host("foo")));
}
+TEST("require that invalid socket spec is not valid") {
+ EXPECT_FALSE(SocketSpec::invalid.valid());
+}
+
TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/vespalib/src/tests/net/sync_crypto_socket/sync_crypto_socket_test.cpp b/vespalib/src/tests/net/sync_crypto_socket/sync_crypto_socket_test.cpp
index 76ecd9453b6..56767051dad 100644
--- a/vespalib/src/tests/net/sync_crypto_socket/sync_crypto_socket_test.cpp
+++ b/vespalib/src/tests/net/sync_crypto_socket/sync_crypto_socket_test.cpp
@@ -17,6 +17,7 @@
#include <fcntl.h>
using namespace vespalib;
+using namespace vespalib::test;
struct SocketPair {
SocketHandle client;
@@ -97,7 +98,9 @@ void verify_socket_io(SyncCryptoSocket &socket, bool is_server) {
void verify_crypto_socket(SocketPair &sockets, CryptoEngine &engine, bool is_server) {
SocketHandle &my_handle = is_server ? sockets.server : sockets.client;
my_handle.set_blocking(false);
- SyncCryptoSocket::UP my_socket = SyncCryptoSocket::create(engine, std::move(my_handle), is_server);
+ SyncCryptoSocket::UP my_socket = is_server
+ ? SyncCryptoSocket::create_server(engine, std::move(my_handle))
+ : SyncCryptoSocket::create_client(engine, std::move(my_handle), local_spec);
ASSERT_TRUE(my_socket);
TEST_DO(verify_socket_io(*my_socket, is_server));
TEST_DO(verify_graceful_shutdown(*my_socket, is_server));
@@ -118,19 +121,19 @@ TEST_MT_FFF("require that encrypted sync socket io works with XorCryptoEngine",
}
TEST_MT_FFF("require that encrypted sync socket io works with TlsCryptoEngine",
- 2, SocketPair(), TlsCryptoEngine(vespalib::test::make_tls_options_for_testing()), TimeBomb(60))
+ 2, SocketPair(), TlsCryptoEngine(make_tls_options_for_testing()), TimeBomb(60))
{
TEST_DO(verify_crypto_socket(f1, f2, (thread_id == 0)));
}
TEST_MT_FFF("require that encrypted sync socket io works with MaybeTlsCryptoEngine(true)",
- 2, SocketPair(), MaybeTlsCryptoEngine(std::make_shared<TlsCryptoEngine>(vespalib::test::make_tls_options_for_testing()), true), TimeBomb(60))
+ 2, SocketPair(), MaybeTlsCryptoEngine(std::make_shared<TlsCryptoEngine>(make_tls_options_for_testing()), true), TimeBomb(60))
{
TEST_DO(verify_crypto_socket(f1, f2, (thread_id == 0)));
}
TEST_MT_FFF("require that encrypted sync socket io works with MaybeTlsCryptoEngine(false)",
- 2, SocketPair(), MaybeTlsCryptoEngine(std::make_shared<TlsCryptoEngine>(vespalib::test::make_tls_options_for_testing()), false), TimeBomb(60))
+ 2, SocketPair(), MaybeTlsCryptoEngine(std::make_shared<TlsCryptoEngine>(make_tls_options_for_testing()), false), TimeBomb(60))
{
TEST_DO(verify_crypto_socket(f1, f2, (thread_id == 0)));
}
diff --git a/vespalib/src/tests/portal/portal_test.cpp b/vespalib/src/tests/portal/portal_test.cpp
index e54700306fe..0bd029c0c3a 100644
--- a/vespalib/src/tests/portal/portal_test.cpp
+++ b/vespalib/src/tests/portal/portal_test.cpp
@@ -14,13 +14,14 @@
#include <vespa/vespalib/util/latch.h>
using namespace vespalib;
+using namespace vespalib::test;
//-----------------------------------------------------------------------------
vespalib::string do_http(int port, CryptoEngine::SP crypto, const vespalib::string &method, const vespalib::string &uri, bool send_host = true) {
auto socket = SocketSpec::from_port(port).client_address().connect();
ASSERT_TRUE(socket.valid());
- auto conn = SyncCryptoSocket::create(*crypto, std::move(socket), false);
+ auto conn = SyncCryptoSocket::create_client(*crypto, std::move(socket), local_spec);
vespalib::string http_req = vespalib::make_string("%s %s HTTP/1.1\r\n"
"My-Header: my value\r\n"
"%s"
@@ -75,7 +76,7 @@ Encryption::~Encryption() = default;
auto null_crypto() { return std::make_shared<NullCryptoEngine>(); }
auto xor_crypto() { return std::make_shared<XorCryptoEngine>(); }
-auto tls_crypto() { return std::make_shared<TlsCryptoEngine>(vespalib::test::make_tls_options_for_testing()); }
+auto tls_crypto() { return std::make_shared<TlsCryptoEngine>(make_tls_options_for_testing()); }
auto maybe_tls_crypto(bool client_tls) { return std::make_shared<MaybeTlsCryptoEngine>(tls_crypto(), client_tls); }
std::vector<Encryption> crypto_list = {{"no encryption", null_crypto()},
@@ -260,18 +261,18 @@ TEST("require that connection errors do not block shutdown by leaking resources"
auto bound = portal->bind("/test", handler);
{ // close before sending anything
auto socket = SocketSpec::from_port(portal->listen_port()).client_address().connect();
- auto conn = SyncCryptoSocket::create(*crypto.engine, std::move(socket), false);
+ auto conn = SyncCryptoSocket::create_client(*crypto.engine, std::move(socket), local_spec);
}
{ // send partial request then close connection
auto socket = SocketSpec::from_port(portal->listen_port()).client_address().connect();
- auto conn = SyncCryptoSocket::create(*crypto.engine, std::move(socket), false);
+ auto conn = SyncCryptoSocket::create_client(*crypto.engine, std::move(socket), local_spec);
vespalib::string req = "GET /test HTTP/1.1\r\n"
"Host: local";
ASSERT_EQUAL(conn->write(req.data(), req.size()), ssize_t(req.size()));
}
{ // send request then close without reading response
auto socket = SocketSpec::from_port(portal->listen_port()).client_address().connect();
- auto conn = SyncCryptoSocket::create(*crypto.engine, std::move(socket), false);
+ auto conn = SyncCryptoSocket::create_client(*crypto.engine, std::move(socket), local_spec);
vespalib::string req = "GET /test HTTP/1.1\r\n"
"Host: localhost\r\n"
"\r\n";
diff --git a/vespalib/src/vespa/vespalib/net/crypto_engine.cpp b/vespalib/src/vespa/vespalib/net/crypto_engine.cpp
index a52d4eeb690..a92b0e06bbe 100644
--- a/vespalib/src/vespa/vespalib/net/crypto_engine.cpp
+++ b/vespalib/src/vespa/vespalib/net/crypto_engine.cpp
@@ -250,16 +250,29 @@ CryptoEngine::get_default()
}
CryptoSocket::UP
-NullCryptoEngine::create_crypto_socket(SocketHandle socket, bool is_server)
+NullCryptoEngine::create_client_crypto_socket(SocketHandle socket, const SocketSpec &)
{
- net::tls::ConnectionStatistics::get(is_server).inc_insecure_connections();
+ net::tls::ConnectionStatistics::get(false).inc_insecure_connections();
return std::make_unique<NullCryptoSocket>(std::move(socket));
}
CryptoSocket::UP
-XorCryptoEngine::create_crypto_socket(SocketHandle socket, bool is_server)
+NullCryptoEngine::create_server_crypto_socket(SocketHandle socket)
{
- return std::make_unique<XorCryptoSocket>(std::move(socket), is_server);
+ net::tls::ConnectionStatistics::get(true).inc_insecure_connections();
+ return std::make_unique<NullCryptoSocket>(std::move(socket));
+}
+
+CryptoSocket::UP
+XorCryptoEngine::create_client_crypto_socket(SocketHandle socket, const SocketSpec &)
+{
+ return std::make_unique<XorCryptoSocket>(std::move(socket), false);
+}
+
+CryptoSocket::UP
+XorCryptoEngine::create_server_crypto_socket(SocketHandle socket)
+{
+ return std::make_unique<XorCryptoSocket>(std::move(socket), true);
}
} // namespace vespalib
diff --git a/vespalib/src/vespa/vespalib/net/crypto_engine.h b/vespalib/src/vespa/vespalib/net/crypto_engine.h
index 1cb1305e039..4deacf9a6c7 100644
--- a/vespalib/src/vespa/vespalib/net/crypto_engine.h
+++ b/vespalib/src/vespa/vespalib/net/crypto_engine.h
@@ -9,6 +9,8 @@
namespace vespalib {
+class SocketSpec;
+
/**
* Component responsible for wrapping low-level sockets into
* appropriate CryptoSocket instances. This is the top-level interface
@@ -17,7 +19,8 @@ namespace vespalib {
**/
struct CryptoEngine {
using SP = std::shared_ptr<CryptoEngine>;
- virtual CryptoSocket::UP create_crypto_socket(SocketHandle socket, bool is_server) = 0;
+ virtual CryptoSocket::UP create_client_crypto_socket(SocketHandle socket, const SocketSpec &spec) = 0;
+ virtual CryptoSocket::UP create_server_crypto_socket(SocketHandle socket) = 0;
virtual ~CryptoEngine();
static CryptoEngine::SP get_default();
};
@@ -26,7 +29,8 @@ struct CryptoEngine {
* Crypto engine without encryption.
**/
struct NullCryptoEngine : public CryptoEngine {
- CryptoSocket::UP create_crypto_socket(SocketHandle socket, bool is_server) override;
+ CryptoSocket::UP create_client_crypto_socket(SocketHandle socket, const SocketSpec &spec) override;
+ CryptoSocket::UP create_server_crypto_socket(SocketHandle socket) override;
};
/**
@@ -35,7 +39,8 @@ struct NullCryptoEngine : public CryptoEngine {
* from TLS.
**/
struct XorCryptoEngine : public CryptoEngine {
- CryptoSocket::UP create_crypto_socket(SocketHandle socket, bool is_server) override;
+ CryptoSocket::UP create_client_crypto_socket(SocketHandle socket, const SocketSpec &spec) override;
+ CryptoSocket::UP create_server_crypto_socket(SocketHandle socket) override;
};
} // namespace vespalib
diff --git a/vespalib/src/vespa/vespalib/net/socket_spec.cpp b/vespalib/src/vespa/vespalib/net/socket_spec.cpp
index d1376ce1dd7..06682086670 100644
--- a/vespalib/src/vespa/vespalib/net/socket_spec.cpp
+++ b/vespalib/src/vespa/vespalib/net/socket_spec.cpp
@@ -41,6 +41,8 @@ SocketSpec::address(bool server) const
return SocketAddress();
}
+SocketSpec SocketSpec::invalid;
+
SocketSpec::SocketSpec(const vespalib::string &spec)
: SocketSpec()
{
diff --git a/vespalib/src/vespa/vespalib/net/socket_spec.h b/vespalib/src/vespa/vespalib/net/socket_spec.h
index f28b14573ac..01af382d638 100644
--- a/vespalib/src/vespa/vespalib/net/socket_spec.h
+++ b/vespalib/src/vespa/vespalib/net/socket_spec.h
@@ -24,6 +24,7 @@ private:
: _type(type), _node(node), _port(port) {}
SocketAddress address(bool server) const;
public:
+ static SocketSpec invalid;
explicit SocketSpec(const vespalib::string &spec);
vespalib::string spec() const;
SocketSpec replace_host(const vespalib::string &new_host) const;
diff --git a/vespalib/src/vespa/vespalib/net/sync_crypto_socket.cpp b/vespalib/src/vespa/vespalib/net/sync_crypto_socket.cpp
index 29388035bda..3aa2d3b0683 100644
--- a/vespalib/src/vespa/vespalib/net/sync_crypto_socket.cpp
+++ b/vespalib/src/vespa/vespalib/net/sync_crypto_socket.cpp
@@ -29,6 +29,25 @@ void set_blocking(int fd) {
} // namespace vespalib::<unnamed>
+SyncCryptoSocket::UP
+SyncCryptoSocket::create(CryptoSocket::UP socket)
+{
+ set_blocking(socket->get_fd());
+ for (;;) {
+ switch (socket->handshake()) {
+ case CryptoSocket::HandshakeResult::FAIL:
+ return std::unique_ptr<SyncCryptoSocket>(nullptr);
+ case CryptoSocket::HandshakeResult::DONE:
+ return UP(new SyncCryptoSocket(std::move(socket)));
+ case CryptoSocket::HandshakeResult::NEED_READ:
+ case CryptoSocket::HandshakeResult::NEED_WRITE:
+ break;
+ case CryptoSocket::HandshakeResult::NEED_WORK:
+ socket->do_handshake_work();
+ }
+ }
+}
+
SyncCryptoSocket::~SyncCryptoSocket() = default;
ssize_t
@@ -90,23 +109,15 @@ SyncCryptoSocket::half_close()
}
SyncCryptoSocket::UP
-SyncCryptoSocket::create(CryptoEngine &engine, SocketHandle socket, bool is_server)
+SyncCryptoSocket::create_client(CryptoEngine &engine, SocketHandle socket, const SocketSpec &spec)
{
- auto crypto_socket = engine.create_crypto_socket(std::move(socket), is_server);
- set_blocking(crypto_socket->get_fd());
- for (;;) {
- switch (crypto_socket->handshake()) {
- case CryptoSocket::HandshakeResult::FAIL:
- return std::unique_ptr<SyncCryptoSocket>(nullptr);
- case CryptoSocket::HandshakeResult::DONE:
- return UP(new SyncCryptoSocket(std::move(crypto_socket)));
- case CryptoSocket::HandshakeResult::NEED_READ:
- case CryptoSocket::HandshakeResult::NEED_WRITE:
- break;
- case CryptoSocket::HandshakeResult::NEED_WORK:
- crypto_socket->do_handshake_work();
- }
- }
+ return create(engine.create_client_crypto_socket(std::move(socket), spec));
+}
+
+SyncCryptoSocket::UP
+SyncCryptoSocket::create_server(CryptoEngine &engine, SocketHandle socket)
+{
+ return create(engine.create_server_crypto_socket(std::move(socket)));
}
} // namespace vespalib
diff --git a/vespalib/src/vespa/vespalib/net/sync_crypto_socket.h b/vespalib/src/vespa/vespalib/net/sync_crypto_socket.h
index 00d6cbca0db..36fcfe12ed9 100644
--- a/vespalib/src/vespa/vespalib/net/sync_crypto_socket.h
+++ b/vespalib/src/vespa/vespalib/net/sync_crypto_socket.h
@@ -19,17 +19,20 @@ namespace vespalib {
**/
class SyncCryptoSocket
{
+public:
+ using UP = std::unique_ptr<SyncCryptoSocket>;
private:
CryptoSocket::UP _socket;
SmartBuffer _buffer;
SyncCryptoSocket(CryptoSocket::UP socket) : _socket(std::move(socket)), _buffer(0) {}
+ static UP create(CryptoSocket::UP socket);
public:
- using UP = std::unique_ptr<SyncCryptoSocket>;
~SyncCryptoSocket();
ssize_t read(char *buf, size_t len);
ssize_t write(const char *buf, size_t len);
ssize_t half_close();
- static UP create(CryptoEngine &engine, SocketHandle socket, bool is_server);
+ static UP create_client(CryptoEngine &engine, SocketHandle socket, const SocketSpec &spec);
+ static UP create_server(CryptoEngine &engine, SocketHandle socket);
};
} // namespace vespalib
diff --git a/vespalib/src/vespa/vespalib/net/tls/auto_reloading_tls_crypto_engine.cpp b/vespalib/src/vespa/vespalib/net/tls/auto_reloading_tls_crypto_engine.cpp
index 5f20280e0e2..c425ab75ce8 100644
--- a/vespalib/src/vespa/vespalib/net/tls/auto_reloading_tls_crypto_engine.cpp
+++ b/vespalib/src/vespa/vespalib/net/tls/auto_reloading_tls_crypto_engine.cpp
@@ -91,13 +91,22 @@ AutoReloadingTlsCryptoEngine::EngineSP AutoReloadingTlsCryptoEngine::acquire_cur
return _current_engine;
}
-CryptoSocket::UP AutoReloadingTlsCryptoEngine::create_crypto_socket(SocketHandle socket, bool is_server) {
- return acquire_current_engine()->create_crypto_socket(std::move(socket), is_server);
+CryptoSocket::UP AutoReloadingTlsCryptoEngine::create_client_crypto_socket(SocketHandle socket, const SocketSpec &spec) {
+ return acquire_current_engine()->create_client_crypto_socket(std::move(socket), spec);
+}
+
+CryptoSocket::UP AutoReloadingTlsCryptoEngine::create_server_crypto_socket(SocketHandle socket) {
+ return acquire_current_engine()->create_server_crypto_socket(std::move(socket));
+}
+
+std::unique_ptr<TlsCryptoSocket>
+AutoReloadingTlsCryptoEngine::create_tls_client_crypto_socket(SocketHandle socket, const SocketSpec &spec) {
+ return acquire_current_engine()->create_tls_client_crypto_socket(std::move(socket), spec);
}
std::unique_ptr<TlsCryptoSocket>
-AutoReloadingTlsCryptoEngine::create_tls_crypto_socket(SocketHandle socket, bool is_server) {
- return acquire_current_engine()->create_tls_crypto_socket(std::move(socket), is_server);
+AutoReloadingTlsCryptoEngine::create_tls_server_crypto_socket(SocketHandle socket) {
+ return acquire_current_engine()->create_tls_server_crypto_socket(std::move(socket));
}
}
diff --git a/vespalib/src/vespa/vespalib/net/tls/auto_reloading_tls_crypto_engine.h b/vespalib/src/vespa/vespalib/net/tls/auto_reloading_tls_crypto_engine.h
index 6287fdd4f63..e268cbc8f1a 100644
--- a/vespalib/src/vespa/vespalib/net/tls/auto_reloading_tls_crypto_engine.h
+++ b/vespalib/src/vespa/vespalib/net/tls/auto_reloading_tls_crypto_engine.h
@@ -45,8 +45,10 @@ public:
EngineSP acquire_current_engine() const;
- CryptoSocket::UP create_crypto_socket(SocketHandle socket, bool is_server) override;
- std::unique_ptr<TlsCryptoSocket> create_tls_crypto_socket(SocketHandle socket, bool is_server) override;
+ CryptoSocket::UP create_client_crypto_socket(SocketHandle socket, const SocketSpec &spec) override;
+ CryptoSocket::UP create_server_crypto_socket(SocketHandle socket) override;
+ std::unique_ptr<TlsCryptoSocket> create_tls_client_crypto_socket(SocketHandle socket, const SocketSpec &spec) override;
+ std::unique_ptr<TlsCryptoSocket> create_tls_server_crypto_socket(SocketHandle socket) override;
};
}
diff --git a/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_engine.cpp b/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_engine.cpp
index 891f8cdab23..f7f0284bded 100644
--- a/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_engine.cpp
+++ b/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_engine.cpp
@@ -6,15 +6,19 @@
namespace vespalib {
CryptoSocket::UP
-MaybeTlsCryptoEngine::create_crypto_socket(SocketHandle socket, bool is_server)
+MaybeTlsCryptoEngine::create_client_crypto_socket(SocketHandle socket, const SocketSpec &spec)
{
- if (is_server) {
- return std::make_unique<MaybeTlsCryptoSocket>(std::move(socket), _tls_engine);
- } else if (_use_tls_when_client) {
- return _tls_engine->create_crypto_socket(std::move(socket), false);
+ if (_use_tls_when_client) {
+ return _tls_engine->create_client_crypto_socket(std::move(socket), spec);
} else {
- return _null_engine->create_crypto_socket(std::move(socket), false);
+ return _null_engine->create_client_crypto_socket(std::move(socket), spec);
}
}
+CryptoSocket::UP
+MaybeTlsCryptoEngine::create_server_crypto_socket(SocketHandle socket)
+{
+ return std::make_unique<MaybeTlsCryptoSocket>(std::move(socket), _tls_engine);
+}
+
} // namespace vespalib
diff --git a/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_engine.h b/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_engine.h
index 29909fa115d..147a770bc8f 100644
--- a/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_engine.h
+++ b/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_engine.h
@@ -28,7 +28,8 @@ public:
: _null_engine(std::make_shared<NullCryptoEngine>()),
_tls_engine(std::move(tls_engine)),
_use_tls_when_client(use_tls_when_client) {}
- CryptoSocket::UP create_crypto_socket(SocketHandle socket, bool is_server) override;
+ CryptoSocket::UP create_client_crypto_socket(SocketHandle socket, const SocketSpec &spec) override;
+ CryptoSocket::UP create_server_crypto_socket(SocketHandle socket) override;
};
} // namespace vespalib
diff --git a/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_socket.cpp b/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_socket.cpp
index 9af6703acbc..8ab6adad2e5 100644
--- a/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_socket.cpp
+++ b/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_socket.cpp
@@ -50,7 +50,7 @@ public:
}
if (looksLikeTlsToMe(src.data)) {
CryptoSocket::UP &self = _self; // need copy due to self destruction
- auto tls_socket = _factory->create_tls_crypto_socket(std::move(_socket), true);
+ auto tls_socket = _factory->create_tls_server_crypto_socket(std::move(_socket));
tls_socket->inject_read_data(src.data, src.size);
self = std::move(tls_socket);
return self->handshake();
diff --git a/vespalib/src/vespa/vespalib/net/tls/tls_crypto_engine.cpp b/vespalib/src/vespa/vespalib/net/tls/tls_crypto_engine.cpp
index 58d99cc7108..d0475f3e88d 100644
--- a/vespalib/src/vespa/vespalib/net/tls/tls_crypto_engine.cpp
+++ b/vespalib/src/vespa/vespalib/net/tls/tls_crypto_engine.cpp
@@ -12,9 +12,17 @@ TlsCryptoEngine::TlsCryptoEngine(net::tls::TransportSecurityOptions tls_opts, ne
}
std::unique_ptr<TlsCryptoSocket>
-TlsCryptoEngine::create_tls_crypto_socket(SocketHandle socket, bool is_server)
+TlsCryptoEngine::create_tls_client_crypto_socket(SocketHandle socket, const SocketSpec &)
{
- auto mode = is_server ? net::tls::CryptoCodec::Mode::Server : net::tls::CryptoCodec::Mode::Client;
+ auto mode = net::tls::CryptoCodec::Mode::Client;
+ auto codec = net::tls::CryptoCodec::create_default_codec(_tls_ctx, SocketAddress::peer_address(socket.get()), mode);
+ return std::make_unique<net::tls::CryptoCodecAdapter>(std::move(socket), std::move(codec));
+}
+
+std::unique_ptr<TlsCryptoSocket>
+TlsCryptoEngine::create_tls_server_crypto_socket(SocketHandle socket)
+{
+ auto mode = net::tls::CryptoCodec::Mode::Server;
auto codec = net::tls::CryptoCodec::create_default_codec(_tls_ctx, SocketAddress::peer_address(socket.get()), mode);
return std::make_unique<net::tls::CryptoCodecAdapter>(std::move(socket), std::move(codec));
}
diff --git a/vespalib/src/vespa/vespalib/net/tls/tls_crypto_engine.h b/vespalib/src/vespa/vespalib/net/tls/tls_crypto_engine.h
index dc7d7eaf9ce..5e760cf5585 100644
--- a/vespalib/src/vespa/vespalib/net/tls/tls_crypto_engine.h
+++ b/vespalib/src/vespa/vespalib/net/tls/tls_crypto_engine.h
@@ -11,7 +11,8 @@ namespace vespalib {
class AbstractTlsCryptoEngine : public CryptoEngine {
public:
- virtual std::unique_ptr<TlsCryptoSocket> create_tls_crypto_socket(SocketHandle socket, bool is_server) = 0;
+ virtual std::unique_ptr<TlsCryptoSocket> create_tls_client_crypto_socket(SocketHandle socket, const SocketSpec &spec) = 0;
+ virtual std::unique_ptr<TlsCryptoSocket> create_tls_server_crypto_socket(SocketHandle socket) = 0;
};
/**
@@ -24,9 +25,13 @@ private:
public:
explicit TlsCryptoEngine(net::tls::TransportSecurityOptions tls_opts,
net::tls::AuthorizationMode authz_mode = net::tls::AuthorizationMode::Enforce);
- std::unique_ptr<TlsCryptoSocket> create_tls_crypto_socket(SocketHandle socket, bool is_server) override;
- CryptoSocket::UP create_crypto_socket(SocketHandle socket, bool is_server) override {
- return create_tls_crypto_socket(std::move(socket), is_server);
+ std::unique_ptr<TlsCryptoSocket> create_tls_client_crypto_socket(SocketHandle socket, const SocketSpec &spec) override;
+ std::unique_ptr<TlsCryptoSocket> create_tls_server_crypto_socket(SocketHandle socket) override;
+ CryptoSocket::UP create_client_crypto_socket(SocketHandle socket, const SocketSpec &spec) override {
+ return create_tls_client_crypto_socket(std::move(socket), spec);
+ }
+ CryptoSocket::UP create_server_crypto_socket(SocketHandle socket) override {
+ return create_tls_server_crypto_socket(std::move(socket));
}
std::shared_ptr<net::tls::TlsContext> tls_context() const noexcept { return _tls_ctx; };
diff --git a/vespalib/src/vespa/vespalib/portal/portal.cpp b/vespalib/src/vespa/vespalib/portal/portal.cpp
index 47719ea4c69..a6d44348e5e 100644
--- a/vespalib/src/vespa/vespalib/portal/portal.cpp
+++ b/vespalib/src/vespa/vespalib/portal/portal.cpp
@@ -143,7 +143,7 @@ Portal::handle_accept(portal::HandleGuard guard, SocketHandle socket)
{
socket.set_blocking(false);
socket.set_keepalive(true);
- new HttpConnection(std::move(guard), _reactor, _crypto->create_crypto_socket(std::move(socket), true),
+ new HttpConnection(std::move(guard), _reactor, _crypto->create_server_crypto_socket(std::move(socket)),
[this](HttpConnection *conn)
{
handle_http(conn);
diff --git a/vespalib/src/vespa/vespalib/test/make_tls_options_for_testing.cpp b/vespalib/src/vespa/vespalib/test/make_tls_options_for_testing.cpp
index c685bffc23e..dcd2ced8036 100644
--- a/vespalib/src/vespa/vespalib/test/make_tls_options_for_testing.cpp
+++ b/vespalib/src/vespa/vespalib/test/make_tls_options_for_testing.cpp
@@ -67,6 +67,8 @@ npxYSKVCyo3a/Vo33V8/H0WgOXioKEZJxA==
namespace vespalib::test {
+SocketSpec local_spec("tcp/localhost:123");
+
vespalib::net::tls::TransportSecurityOptions make_tls_options_for_testing() {
return vespalib::net::tls::TransportSecurityOptions(ca_pem, cert_pem, key_pem);
}
diff --git a/vespalib/src/vespa/vespalib/test/make_tls_options_for_testing.h b/vespalib/src/vespa/vespalib/test/make_tls_options_for_testing.h
index a1f1d5958f9..41e5d7cc86d 100644
--- a/vespalib/src/vespa/vespalib/test/make_tls_options_for_testing.h
+++ b/vespalib/src/vespa/vespalib/test/make_tls_options_for_testing.h
@@ -2,11 +2,19 @@
#pragma once
+#include <vespa/vespalib/net/socket_spec.h>
#include <vespa/vespalib/net/tls/transport_security_options.h>
namespace vespalib::test {
/**
+ * A socket spec representing "tcp/localhost:123". Used by unit tests
+ * performing hostname verification against the tls options created
+ * below.
+ **/
+extern SocketSpec local_spec;
+
+/**
* Make security options allowing you to talk to yourself using
* TLS. This is intended for testing purposes only.
**/