102 lines
3.1 KiB
Diff
102 lines
3.1 KiB
Diff
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
|
||
index 262e465..1bee9a6 100644
|
||
--- a/src/libstore/remote-store.cc
|
||
+++ b/src/libstore/remote-store.cc
|
||
@@ -16,6 +16,7 @@
|
||
|
||
#include <iostream>
|
||
#include <unistd.h>
|
||
+#include <netdb.h>
|
||
#include <cstring>
|
||
|
||
namespace nix {
|
||
@@ -55,9 +56,9 @@ void RemoteStore::openConnection(bool reserveSpace)
|
||
if (remoteMode == "daemon")
|
||
/* Connect to a daemon that does the privileged work for
|
||
us. */
|
||
- connectToDaemon();
|
||
+ connectToDaemonUNIX();
|
||
else
|
||
- throw Error(format("invalid setting for NIX_REMOTE, ‘%1%’") % remoteMode);
|
||
+ connectToDaemonINET(remoteMode);
|
||
|
||
from.fd = fdSocket;
|
||
to.fd = fdSocket;
|
||
@@ -95,7 +96,7 @@ void RemoteStore::openConnection(bool reserveSpace)
|
||
}
|
||
|
||
|
||
-void RemoteStore::connectToDaemon()
|
||
+void RemoteStore::connectToDaemonUNIX()
|
||
{
|
||
fdSocket = socket(PF_UNIX, SOCK_STREAM, 0);
|
||
if (fdSocket == -1)
|
||
@@ -128,6 +129,53 @@ void RemoteStore::connectToDaemon()
|
||
}
|
||
|
||
|
||
+
|
||
+void RemoteStore::connectToDaemonINET(const string & remoteAddress)
|
||
+{
|
||
+ size_t remoteColonOffset = remoteAddress.find(':');
|
||
+ if (remoteColonOffset == string::npos)
|
||
+ throw Error(format("invalid daemon address ‘%1%’ (should be daemon or host:port)") % remoteAddress);
|
||
+
|
||
+ string remoteHost = remoteAddress.substr(0,remoteColonOffset);
|
||
+ string remoteService = remoteAddress.substr(remoteColonOffset+1);
|
||
+
|
||
+ addrinfo addrHints;
|
||
+ addrinfo* addrResults;
|
||
+
|
||
+ 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);
|
||
+ if (result != 0)
|
||
+ throw Error(format("unable to lookup daemon address ‘%1%’") % remoteAddress);
|
||
+ std::unique_ptr<addrinfo,void (&)(addrinfo *)> addrResults_gc(addrResults,freeaddrinfo);
|
||
+
|
||
+ int remoteSocket;
|
||
+ addrinfo* addrIter;
|
||
+ for (addrIter = addrResults; addrIter; addrIter = addrIter->ai_next) {
|
||
+ remoteSocket = socket(addrIter->ai_family, addrIter->ai_socktype, addrIter->ai_protocol);
|
||
+ if (remoteSocket == -1)
|
||
+ continue;
|
||
+
|
||
+ int result = connect(remoteSocket, addrIter->ai_addr, addrIter->ai_addrlen);
|
||
+ if (result == -1) {
|
||
+ close(remoteSocket);
|
||
+ continue;
|
||
+ }
|
||
+
|
||
+ fdSocket = remoteSocket;
|
||
+ break;
|
||
+ }
|
||
+ if (addrIter == 0)
|
||
+ throw Error(format("unable to connect to daemon at ‘%1%’") % remoteAddress);
|
||
+
|
||
+ fdSocket = remoteSocket;
|
||
+}
|
||
+
|
||
+
|
||
RemoteStore::~RemoteStore()
|
||
{
|
||
try {
|
||
diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh
|
||
index b0787c0..6fd404f 100644
|
||
--- a/src/libstore/remote-store.hh
|
||
+++ b/src/libstore/remote-store.hh
|
||
@@ -101,7 +101,8 @@ private:
|
||
|
||
void processStderr(Sink * sink = 0, Source * source = 0);
|
||
|
||
- void connectToDaemon();
|
||
+ void connectToDaemonUNIX();
|
||
+ void connectToDaemonINET(const string & remoteAddress);
|
||
|
||
void setOptions();
|
||
};
|