aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/net.cpp2
-rw-r--r--src/netbase.cpp18
-rw-r--r--src/netbase.h39
-rw-r--r--src/rpc/net.cpp2
4 files changed, 55 insertions, 6 deletions
diff --git a/src/net.cpp b/src/net.cpp
index 345c1c8b4b..2cc85aa488 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -483,7 +483,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
addr_bind = CAddress{conn.me, NODE_NONE};
}
} else if (use_proxy) {
- LogPrintLevel(BCLog::PROXY, BCLog::Level::Debug, "Using proxy: %s to connect to %s:%s\n", proxy.proxy.ToStringAddrPort(), addrConnect.ToStringAddr(), addrConnect.GetPort());
+ LogPrintLevel(BCLog::PROXY, BCLog::Level::Debug, "Using proxy: %s to connect to %s:%s\n", proxy.ToString(), addrConnect.ToStringAddr(), addrConnect.GetPort());
sock = ConnectThroughProxy(proxy, addrConnect.ToStringAddr(), addrConnect.GetPort(), proxyConnectionFailed);
} else {
// no proxy needed (none set for target network)
diff --git a/src/netbase.cpp b/src/netbase.cpp
index 93a84a73b0..d3c3c36b37 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -216,6 +216,24 @@ CService LookupNumeric(const std::string& name, uint16_t portDefault, DNSLookupF
return Lookup(name, portDefault, /*fAllowLookup=*/false, dns_lookup_function).value_or(CService{});
}
+bool IsUnixSocketPath(const std::string& name)
+{
+#if HAVE_SOCKADDR_UN
+ if (name.find(ADDR_PREFIX_UNIX) != 0) return false;
+
+ // Split off "unix:" prefix
+ std::string str{name.substr(ADDR_PREFIX_UNIX.length())};
+
+ // Path size limit is platform-dependent
+ // see https://manpages.ubuntu.com/manpages/xenial/en/man7/unix.7.html
+ if (str.size() + 1 > sizeof(((sockaddr_un*)nullptr)->sun_path)) return false;
+
+ return true;
+#else
+ return false;
+#endif
+}
+
/** SOCKS version */
enum SOCKSVersion: uint8_t {
SOCKS4 = 0x04,
diff --git a/src/netbase.h b/src/netbase.h
index c54056d25c..e3b7da470c 100644
--- a/src/netbase.h
+++ b/src/netbase.h
@@ -27,6 +27,9 @@ static const int DEFAULT_CONNECT_TIMEOUT = 5000;
//! -dns default
static const int DEFAULT_NAME_LOOKUP = true;
+/** Prefix for unix domain socket addresses (which are local filesystem paths) */
+const std::string ADDR_PREFIX_UNIX = "unix:";
+
enum class ConnectionDirection {
None = 0,
In = (1U << 0),
@@ -43,16 +46,44 @@ static inline bool operator&(ConnectionDirection a, ConnectionDirection b) {
return (underlying(a) & underlying(b));
}
+/**
+ * Check if a string is a valid UNIX domain socket path
+ *
+ * @param name The string provided by the user representing a local path
+ *
+ * @returns Whether the string has proper format, length, and points to an existing file path
+ */
+bool IsUnixSocketPath(const std::string& name);
+
class Proxy
{
public:
- Proxy(): randomize_credentials(false) {}
- explicit Proxy(const CService &_proxy, bool _randomize_credentials=false): proxy(_proxy), randomize_credentials(_randomize_credentials) {}
-
- bool IsValid() const { return proxy.IsValid(); }
+ Proxy(): m_is_unix_socket(false), randomize_credentials(false) {}
+ explicit Proxy(const CService &_proxy, bool _randomize_credentials=false): proxy(_proxy), m_is_unix_socket(false), randomize_credentials(_randomize_credentials) {}
+ explicit Proxy(const std::string path, bool _randomize_credentials=false): m_unix_socket_path(path), m_is_unix_socket(true), randomize_credentials(_randomize_credentials) {}
CService proxy;
+ std::string m_unix_socket_path;
+ bool m_is_unix_socket;
bool randomize_credentials;
+
+ bool IsValid() const
+ {
+ if (m_is_unix_socket) return IsUnixSocketPath(m_unix_socket_path);
+ return proxy.IsValid();
+ }
+
+ sa_family_t GetFamily() const
+ {
+ if (m_is_unix_socket) return AF_UNIX;
+ return proxy.GetSAFamily();
+ }
+
+ std::string ToString() const
+ {
+ if (m_is_unix_socket) return m_unix_socket_path;
+ return proxy.ToStringAddrPort();
+ }
};
/** Credentials for proxy authentication */
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index 5e6f42b596..be07e6c2d5 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -607,7 +607,7 @@ static UniValue GetNetworksInfo()
obj.pushKV("name", GetNetworkName(network));
obj.pushKV("limited", !g_reachable_nets.Contains(network));
obj.pushKV("reachable", g_reachable_nets.Contains(network));
- obj.pushKV("proxy", proxy.IsValid() ? proxy.proxy.ToStringAddrPort() : std::string());
+ obj.pushKV("proxy", proxy.IsValid() ? proxy.ToString() : std::string());
obj.pushKV("proxy_randomize_credentials", proxy.randomize_credentials);
networks.push_back(obj);
}