mirror of
https://github.com/NixOS/nix
synced 2025-07-03 06:11:46 +02:00
WorkerProto: Support fine-grained protocol feature negotiation
Currently, the worker protocol has a version number that we increment whenever we change something in the protocol. However, this can cause a collision between Nix PRs / forks that make protocol changes (e.g. PR #9857 increments the version, which could collide with another PR). So instead, the client and daemon now exchange a set of protocol features (such as `auth-forwarding`). They will use the intersection of the sets of features, i.e. the features they both support. Note that protocol features are completely distinct from `ExperimentalFeature`s.
This commit is contained in:
parent
b13ba7490c
commit
3be7c0037e
6 changed files with 127 additions and 29 deletions
|
@ -5,6 +5,8 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
const std::set<WorkerProto::Feature> WorkerProto::allFeatures{};
|
||||
|
||||
WorkerProto::BasicClientConnection::~BasicClientConnection()
|
||||
{
|
||||
try {
|
||||
|
@ -137,8 +139,21 @@ void WorkerProto::BasicClientConnection::processStderr(bool * daemonException, S
|
|||
}
|
||||
}
|
||||
|
||||
WorkerProto::Version
|
||||
WorkerProto::BasicClientConnection::handshake(BufferedSink & to, Source & from, WorkerProto::Version localVersion)
|
||||
static std::set<WorkerProto::Feature>
|
||||
intersectFeatures(const std::set<WorkerProto::Feature> & a, const std::set<WorkerProto::Feature> & b)
|
||||
{
|
||||
std::set<WorkerProto::Feature> res;
|
||||
for (auto & x : a)
|
||||
if (b.contains(x))
|
||||
res.insert(x);
|
||||
return res;
|
||||
}
|
||||
|
||||
std::tuple<WorkerProto::Version, std::set<WorkerProto::Feature>> WorkerProto::BasicClientConnection::handshake(
|
||||
BufferedSink & to,
|
||||
Source & from,
|
||||
WorkerProto::Version localVersion,
|
||||
const std::set<WorkerProto::Feature> & supportedFeatures)
|
||||
{
|
||||
to << WORKER_MAGIC_1 << localVersion;
|
||||
to.flush();
|
||||
|
@ -153,11 +168,24 @@ WorkerProto::BasicClientConnection::handshake(BufferedSink & to, Source & from,
|
|||
if (GET_PROTOCOL_MINOR(daemonVersion) < 10)
|
||||
throw Error("the Nix daemon version is too old");
|
||||
|
||||
return std::min(daemonVersion, localVersion);
|
||||
auto protoVersion = std::min(daemonVersion, localVersion);
|
||||
|
||||
/* Exchange features. */
|
||||
std::set<WorkerProto::Feature> daemonFeatures;
|
||||
if (GET_PROTOCOL_MINOR(protoVersion) >= 38) {
|
||||
to << supportedFeatures;
|
||||
to.flush();
|
||||
daemonFeatures = readStrings<std::set<WorkerProto::Feature>>(from);
|
||||
}
|
||||
|
||||
return {protoVersion, intersectFeatures(daemonFeatures, supportedFeatures)};
|
||||
}
|
||||
|
||||
WorkerProto::Version
|
||||
WorkerProto::BasicServerConnection::handshake(BufferedSink & to, Source & from, WorkerProto::Version localVersion)
|
||||
std::tuple<WorkerProto::Version, std::set<WorkerProto::Feature>> WorkerProto::BasicServerConnection::handshake(
|
||||
BufferedSink & to,
|
||||
Source & from,
|
||||
WorkerProto::Version localVersion,
|
||||
const std::set<WorkerProto::Feature> & supportedFeatures)
|
||||
{
|
||||
unsigned int magic = readInt(from);
|
||||
if (magic != WORKER_MAGIC_1)
|
||||
|
@ -165,7 +193,18 @@ WorkerProto::BasicServerConnection::handshake(BufferedSink & to, Source & from,
|
|||
to << WORKER_MAGIC_2 << localVersion;
|
||||
to.flush();
|
||||
auto clientVersion = readInt(from);
|
||||
return std::min(clientVersion, localVersion);
|
||||
|
||||
auto protoVersion = std::min(clientVersion, localVersion);
|
||||
|
||||
/* Exchange features. */
|
||||
std::set<WorkerProto::Feature> clientFeatures;
|
||||
if (GET_PROTOCOL_MINOR(protoVersion) >= 38) {
|
||||
clientFeatures = readStrings<std::set<WorkerProto::Feature>>(from);
|
||||
to << supportedFeatures;
|
||||
to.flush();
|
||||
}
|
||||
|
||||
return {protoVersion, intersectFeatures(clientFeatures, supportedFeatures)};
|
||||
}
|
||||
|
||||
WorkerProto::ClientHandshakeInfo WorkerProto::BasicClientConnection::postHandshake(const StoreDirConfig & store)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue