Files
ccpkgs/pkgs/nix/remote.patch
2021-01-28 17:16:11 -05:00

143 lines
4.2 KiB
Diff

diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index f34369d8f..a14191339 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -16,6 +16,7 @@
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
+#include <netdb.h>
#include <cstring>
@@ -134,6 +135,76 @@ ref<RemoteStore::Connection> UDSRemoteStore::openConnection()
}
+TCPRemoteStore::TCPRemoteStore(std::string tcp_path, const Params & params)
+ : Store(params)
+ , LocalFSStore(params)
+ , RemoteStore(params)
+ , path(tcp_path)
+{
+}
+
+
+std::string TCPRemoteStore::getUri()
+{
+ return std::string("tcp://") + path;
+}
+
+
+ref<RemoteStore::Connection> TCPRemoteStore::openConnection()
+{
+ auto conn = make_ref<Connection>();
+
+ size_t remoteColonOffset = path.find(':');
+ if (remoteColonOffset == string::npos)
+ throw Error(format("invalid daemon address '%1%' (should be host:port)") % path);
+
+ string remoteHost = path.substr(0,remoteColonOffset);
+ string remoteService = path.substr(remoteColonOffset+1);
+
+ addrinfo addrHints;
+ addrinfo* addrResults_raw;
+
+ memset(&addrHints,0,sizeof(addrHints));
+ addrHints.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED;
+ addrHints.ai_family = AF_UNSPEC;
+ addrHints.ai_socktype = SOCK_STREAM;
+ addrHints.ai_protocol = 0;
+
+ int result = getaddrinfo(remoteHost.c_str(), remoteService.c_str(), &addrHints, &addrResults_raw);
+ if (result != 0)
+ throw Error(format("unable to lookup daemon address '%1%'") % path);
+ std::unique_ptr<addrinfo,void (&)(addrinfo *)> addrResults(addrResults_raw,freeaddrinfo);
+
+ addrinfo* addrIter;
+ for (addrIter = addrResults.get(); addrIter; addrIter = addrIter->ai_next) {
+ AutoCloseFD remoteSocket = socket(addrIter->ai_family, addrIter->ai_socktype
+ #ifdef SOCK_CLOEXEC
+ | SOCK_CLOEXEC
+ #endif
+ , addrIter->ai_protocol);
+ if (!remoteSocket)
+ continue;
+
+ if (::connect(remoteSocket.get(), addrIter->ai_addr, addrIter->ai_addrlen) == -1)
+ continue;
+
+ conn->fd = std::move(remoteSocket);
+ break;
+ }
+ if (addrIter == 0)
+ throw Error(format("unable to connect to daemon at '%1%'") % path);
+
+ conn->from.fd = conn->fd.get();
+ conn->to.fd = conn->fd.get();
+
+ conn->startTime = std::chrono::steady_clock::now();
+
+ initConnection(*conn);
+
+ return conn;
+}
+
+
void RemoteStore::initConnection(Connection & conn)
{
/* Send the magic greeting, check for the reply. */
@@ -804,14 +875,18 @@ std::exception_ptr RemoteStore::Connection::processStderr(Sink * sink, Source *
return nullptr;
}
-static std::string uriScheme = "unix://";
+static std::string uriSchemeUnix = "unix://";
+static std::string uriSchemeTCP = "tcp://";
static RegisterStoreImplementation regStore([](
const std::string & uri, const Store::Params & params)
-> std::shared_ptr<Store>
{
- if (std::string(uri, 0, uriScheme.size()) != uriScheme) return 0;
- return std::make_shared<UDSRemoteStore>(std::string(uri, uriScheme.size()), params);
+ if (std::string(uri, 0, uriSchemeUnix.size()) == uriSchemeUnix)
+ return std::make_shared<UDSRemoteStore>(std::string(uri, uriSchemeUnix.size()), params);
+ if (std::string(uri, 0, uriSchemeTCP.size()) == uriSchemeTCP)
+ return std::make_shared<TCPRemoteStore>(std::string(uri, uriSchemeTCP.size()), params);
+ return 0;
});
}
diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh
index 1f375dd71..cfd0a7629 100644
--- a/src/libstore/remote-store.hh
+++ b/src/libstore/remote-store.hh
@@ -157,5 +157,26 @@ private:
std::optional<std::string> path;
};
+class TCPRemoteStore : public LocalFSStore, public RemoteStore
+{
+public:
+
+ TCPRemoteStore(std::string path, const Params & params);
+
+ std::string getUri() override;
+
+ bool sameMachine()
+ { return false; }
+
+private:
+
+ struct Connection : RemoteStore::Connection
+ {
+ AutoCloseFD fd;
+ };
+
+ ref<RemoteStore::Connection> openConnection() override;
+ std::string path;
+};
}