summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Powell <petpow@saberuk.com>2019-05-29 13:53:52 +0100
committerPeter Powell <petpow@saberuk.com>2019-05-30 11:51:01 +0100
commit08d2ff86b0c7ed91549d832cf3e572c8623dc8e8 (patch)
treec9de38e9b663dc88cc86e32af900e09e73077ab4
parent33932b95e4b886aec8ac1bf3e3e1665826bcd0ea (diff)
Various improvements to UNIX socket support.
- Allow replacing dead UNIX sockets on startup. - Allow setting the permissions of the UNIX socket. - Expand the UNIX socket path relative to the data directory.
-rw-r--r--docs/conf/inspircd.conf.example29
-rw-r--r--src/listensocket.cpp7
-rw-r--r--src/socket.cpp17
3 files changed, 43 insertions, 10 deletions
diff --git a/docs/conf/inspircd.conf.example b/docs/conf/inspircd.conf.example
index 9baaa5261..f421eb0e8 100644
--- a/docs/conf/inspircd.conf.example
+++ b/docs/conf/inspircd.conf.example
@@ -135,6 +135,7 @@
# information on how to load this module! If you do not load this #
# module, server ports will NOT work! #
+# Listener that binds on a TCP/IP endpoint:
<bind
# address: IP address to bind to if the box that you are hosting
# on has more than one IP, else the ircd will try to bind to all
@@ -175,8 +176,29 @@
# whether the interface that provides the bind address is available. This
# is useful for if you are starting InspIRCd on boot when the server may
# not have brought the network interfaces up yet.
- free="no"
->
+ free="no">
+
+# Listener that binds on a UNIX endpoint (not supported on Windows):
+#<bind
+
+ # path: The location to store the UNIX socket
+ #path="/tmp/inspircd.sock"
+
+ # type: Type of bind block this is. It can either be clients or
+ # servers. Whichever you select will be the only type able to connect
+ # to this bind section.
+ #type="clients"
+
+ # permissions: The octal permissions to set on the UNIX socket after it has
+ # been created. If you are not familiar with octal permissions you should
+ # not define this or refer to http://permissions-calculator.org for help.
+ #permissions=""
+
+ # replace: if the UNIX socket path already exists then remove it before
+ # attempting to create the new one. This is strongly recommended as it
+ # allows InspIRCd to create sockets in cases where it previously did not
+ # shut down cleanly and left a zombie socket behind.
+ #replace="yes">
<bind address="" port="6660-6669" type="clients">
@@ -185,9 +207,6 @@
# module).
#<bind address="" port="7002" type="clients" hook="websocket">
-# EXPERIMENTAL: Listener that binds on a UNIX endpoint instead of a TCP/IP endpoint:
-#<bind path="/tmp/inspircd.sock" type="clients">
-
# You can define a custom <sslprofile> tag which defines the SSL configuration
# for this listener. See the docs page for the SSL module you are using for
# more details.
diff --git a/src/listensocket.cpp b/src/listensocket.cpp
index 60ee0b449..3d6b11568 100644
--- a/src/listensocket.cpp
+++ b/src/listensocket.cpp
@@ -66,6 +66,13 @@ ListenSocket::ListenSocket(ConfigTag* tag, const irc::sockets::sockaddrs& bind_t
#endif
}
+ if (bind_to.family() == AF_UNIX)
+ {
+ unsigned int permissions = tag->getUInt("permissions", 0, 0, 777);
+ if (permissions)
+ chmod(bind_to.str().c_str(), permissions);
+ }
+
SocketEngine::SetReuse(fd);
int rv = SocketEngine::Bind(this->fd, bind_to);
if (rv >= 0)
diff --git a/src/socket.cpp b/src/socket.cpp
index 2daa6a821..26b5aeee3 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -98,24 +98,31 @@ int InspIRCd::BindPorts(FailedPortList& failed_ports)
const std::string path = tag->getString("path");
if (!path.empty())
{
+ // Expand the path relative to the config directory.
+ const std::string fullpath = ServerInstance->Config->Paths.PrependData(path);
+
// UNIX socket paths are length limited to less than PATH_MAX.
irc::sockets::sockaddrs bindspec;
- if (path.length() > std::min(ServerInstance->Config->Limits.MaxHost, sizeof(bindspec.un.sun_path) - 1))
+ if (fullpath.length() > std::min(ServerInstance->Config->Limits.MaxHost, sizeof(bindspec.un.sun_path) - 1))
{
this->Logs->Log("SOCKET", LOG_DEFAULT, "UNIX listener on %s at %s specified a path that is too long!",
- path.c_str(), tag->getTagLocation().c_str());
+ fullpath.c_str(), tag->getTagLocation().c_str());
continue;
}
// Check for characters which are problematic in the IRC message format.
- if (path.find_first_of("\n\r\t!@: ") != std::string::npos)
+ if (fullpath.find_first_of("\n\r\t!@: ") != std::string::npos)
{
this->Logs->Log("SOCKET", LOG_DEFAULT, "UNIX listener on %s at %s specified a path containing invalid characters!",
- path.c_str(), tag->getTagLocation().c_str());
+ fullpath.c_str(), tag->getTagLocation().c_str());
continue;
}
- irc::sockets::untosa(path, bindspec);
+ const bool replace = tag->getBool("replace");
+ if (replace && irc::sockets::isunix(fullpath))
+ remove(fullpath.c_str());
+
+ irc::sockets::untosa(fullpath, bindspec);
if (!BindPort(tag, bindspec, old_ports))
failed_ports.push_back(std::make_pair(bindspec, errno));
else