summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSadie Powell <sadie@witchery.services>2022-12-15 13:07:22 +0000
committerSadie Powell <sadie@witchery.services>2022-12-17 11:50:38 +0000
commitdfdcd3021a482182827ba00782acd5a53442d21a (patch)
treea1fc48af8de2c732a6222c7db9e1c9018de0b785 /src
parent5fa3d8f9297f50e25a7bad6a9bde91b9024330de (diff)
Add support for linking over UNIX sockets.
Diffstat (limited to 'src')
-rw-r--r--src/config.cpp30
-rw-r--r--src/sockets.cpp33
-rw-r--r--src/uplink.cpp4
3 files changed, 48 insertions, 19 deletions
diff --git a/src/config.cpp b/src/config.cpp
index 0d1900268..0503340b0 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -193,19 +193,33 @@ Conf::Conf() : Block(""), EmptyBlock("")
{
Block *uplink = this->GetBlock("uplink", i);
- const Anope::string &host = uplink->Get<const Anope::string>("host");
- bool ipv6 = uplink->Get<bool>("ipv6");
- int port = uplink->Get<int>("port");
- const Anope::string &password = uplink->Get<const Anope::string>("password");
+ int protocol;
+ const Anope::string &protocolstr = uplink->Get<const Anope::string>("protocol", "ipv4");
+ if (protocolstr == "ipv4")
+ protocol = AF_INET;
+ else if (protocolstr == "ipv6")
+ protocol = AF_INET6;
+ else if (protocolstr == "unix")
+ protocol = AF_UNIX;
+ else
+ throw ConfigException("uplink:protocol must be set to ipv4, ipv6, or unix");
+ const Anope::string &host = uplink->Get<const Anope::string>("host");
ValidateNotEmptyOrSpaces("uplink", "host", host);
- ValidateNotZero("uplink", "port", port);
- ValidateNotEmptyOrSpaces("uplink", "password", password);
- if (password.find(' ') != Anope::string::npos || password[0] == ':')
+ int port = 0;
+ if (protocol != AF_UNIX)
+ {
+ ValidateNotZero("uplink", "port", port);
+ port = uplink->Get<int>("port");
+ }
+
+ const Anope::string &password = uplink->Get<const Anope::string>("password");
+ ValidateNotEmptyOrSpaces("uplink", "password", password);
+ if (password[0] == ':')
throw ConfigException("uplink:password is not valid");
- this->Uplinks.emplace_back(host, port, password, ipv6);
+ this->Uplinks.emplace_back(host, port, password, protocol);
}
for (int i = 0; i < this->CountBlock("module"); ++i)
diff --git a/src/sockets.cpp b/src/sockets.cpp
index 061a8eb10..34aa946ba 100644
--- a/src/sockets.cpp
+++ b/src/sockets.cpp
@@ -52,6 +52,8 @@ size_t sockaddrs::size() const
return sizeof(sa4);
case AF_INET6:
return sizeof(sa6);
+ case AF_UNIX:
+ return sizeof(saun);
default:
break;
}
@@ -67,6 +69,8 @@ int sockaddrs::port() const
return ntohs(sa4.sin_port);
case AF_INET6:
return ntohs(sa6.sin6_port);
+ case AF_UNIX:
+ return 0;
default:
break;
}
@@ -88,6 +92,8 @@ Anope::string sockaddrs::addr() const
if (inet_ntop(AF_INET6, &sa6.sin6_addr, address, sizeof(address)))
return address;
break;
+ case AF_UNIX:
+ return saun.sun_path;
default:
break;
}
@@ -187,6 +193,15 @@ void sockaddrs::pton(int type, const Anope::string &address, int pport)
}
break;
}
+ case AF_UNIX:
+ {
+ if (address.length() < sizeof(saun.sun_path))
+ {
+ saun.sun_family = AF_UNIX;
+ memcpy(&saun.sun_path, address.c_str(), address.length() + 1);
+ }
+ break;
+ }
default:
break;
}
@@ -432,7 +447,7 @@ SocketFlag SocketIO::FinishAccept(ClientSocket *cs)
void SocketIO::Bind(Socket *s, const Anope::string &ip, int port)
{
- s->bindaddr.pton(s->IsIPv6() ? AF_INET6 : AF_INET, ip, port);
+ s->bindaddr.pton(s->GetFamily(), ip, port);
if (bind(s->GetFD(), &s->bindaddr.sa, s->bindaddr.size()) == -1)
throw SocketException("Unable to bind to address: " + Anope::LastError());
}
@@ -440,7 +455,7 @@ void SocketIO::Bind(Socket *s, const Anope::string &ip, int port)
void SocketIO::Connect(ConnectionSocket *s, const Anope::string &target, int port)
{
s->flags[SF_CONNECTING] = s->flags[SF_CONNECTED] = false;
- s->conaddr.pton(s->IsIPv6() ? AF_INET6 : AF_INET, target, port);
+ s->conaddr.pton(s->GetFamily(), target, port);
int c = connect(s->GetFD(), &s->conaddr.sa, s->conaddr.size());
if (c == -1)
{
@@ -488,12 +503,12 @@ Socket::Socket()
throw CoreException("Socket::Socket() ?");
}
-Socket::Socket(int s, bool i, int type)
+Socket::Socket(int s, bool f, int type)
{
this->io = &NormalSocketIO;
- this->ipv6 = i;
+ this->family = f;
if (s == -1)
- this->sock = socket(this->ipv6 ? AF_INET6 : AF_INET, type, 0);
+ this->sock = socket(this->family, type, 0);
else
this->sock = s;
this->SetBlocking(false);
@@ -510,14 +525,14 @@ Socket::~Socket()
SocketEngine::Sockets.erase(this->sock);
}
-int Socket::GetFD() const
+int Socket::GetFamily() const
{
- return sock;
+ return family;
}
-bool Socket::IsIPv6() const
+int Socket::GetFD() const
{
- return ipv6;
+ return sock;
}
bool Socket::SetBlocking(bool state)
diff --git a/src/uplink.cpp b/src/uplink.cpp
index 03d8d99f1..db58d71b0 100644
--- a/src/uplink.cpp
+++ b/src/uplink.cpp
@@ -52,12 +52,12 @@ void Uplink::Connect()
if (!Config->GetBlock("serverinfo")->Get<const Anope::string>("localhost").empty())
UplinkSock->Bind(Config->GetBlock("serverinfo")->Get<const Anope::string>("localhost"));
FOREACH_MOD(OnPreServerConnect, ());
- Anope::string ip = Anope::Resolve(u.host, u.ipv6 ? AF_INET6 : AF_INET);
+ Anope::string ip = Anope::Resolve(u.host, u.protocol);
Log(LOG_TERMINAL) << "Attempting to connect to uplink #" << (Anope::CurrentUplink + 1) << " " << u.host << " (" << ip << '/' << u.port << ") with protocol " << IRCD->GetProtocolName();
UplinkSock->Connect(ip, u.port);
}
-UplinkSocket::UplinkSocket() : Socket(-1, Config->Uplinks[Anope::CurrentUplink].ipv6), ConnectionSocket(), BufferedSocket()
+UplinkSocket::UplinkSocket() : Socket(-1, Config->Uplinks[Anope::CurrentUplink].protocol), ConnectionSocket(), BufferedSocket()
{
error = false;
UplinkSock = this;