summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2009-09-02 00:48:32 +0000
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2009-09-02 00:48:32 +0000
commit06e0d5c7f0f78c489090fe5f0c18a91e8cb41ae8 (patch)
treeb05cf1bb463a9fd986768357c717709049f0caa6
parentc4cb1f9477b1fbf8662bedb1c36f84ff6f87e1f3 (diff)
Use a set to mark client SSL ports rather than going by textual IP/port pairs
This theoretically speeds up accepting connections. Visible changes are proper IPv6 port text in 005 output and no possibility of incorrect SSL on addresses that mismatch an incoming port (possible with IPv4 wildcard SSL and IPv6 plaintext on the same port, not that anyone would do such a thing). Bind ports also now tell which SSL module they use in /stats p. git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11629 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r--include/socket.h13
-rw-r--r--src/listensocket.cpp14
-rw-r--r--src/modules/extra/m_ssl_gnutls.cpp83
-rw-r--r--src/modules/extra/m_ssl_openssl.cpp87
-rw-r--r--src/socket.cpp4
5 files changed, 50 insertions, 151 deletions
diff --git a/include/socket.h b/include/socket.h
index d3a45475d..f97630d04 100644
--- a/include/socket.h
+++ b/include/socket.h
@@ -139,10 +139,12 @@ class CoreExport ListenSocketBase : public EventHandler
/** Socket description (shown in stats p) */
std::string desc;
- /** Address socket is bound to */
+ /** Raw address socket is bound to */
std::string bind_addr;
/** Port socket is bound to */
int bind_port;
+ /** Human-readable address/port socket is bound to */
+ std::string bind_desc;
/** The client address if the most recently connected client.
* Should only be used when accepting a new client.
@@ -173,18 +175,17 @@ class CoreExport ListenSocketBase : public EventHandler
}
/** Get description for socket
*/
- const std::string& GetDescription()
- {
- return desc;
- }
+ const std::string& GetDescription() { return desc; }
/** Get port number for socket
*/
- int GetPort() { return bind_port; }
+ const int GetPort() { return bind_port; }
/** Get IP address socket is bound to
*/
const std::string &GetIP() { return bind_addr; }
+ const std::string &GetBindDesc() { return bind_desc; }
+
/** Handles sockets internals crap of a connection, convenience wrapper really
*/
void AcceptInternal();
diff --git a/src/listensocket.cpp b/src/listensocket.cpp
index 663f912e6..df252f18b 100644
--- a/src/listensocket.cpp
+++ b/src/listensocket.cpp
@@ -25,12 +25,18 @@ ListenSocketBase::ListenSocketBase(InspIRCd* Instance, int port, const std::stri
{
irc::sockets::sockaddrs bind_to;
- bind_addr = addr;
- bind_port = port;
-
// canonicalize address if it is defined
- if (!addr.empty() && irc::sockets::aptosa(addr.c_str(), port, &bind_to))
+ if (irc::sockets::aptosa(addr.c_str(), port, &bind_to))
+ {
irc::sockets::satoap(&bind_to, bind_addr, bind_port);
+ bind_desc = irc::sockets::satouser(&bind_to);
+ }
+ else
+ {
+ bind_addr = addr;
+ bind_port = port;
+ bind_desc = addr + ":" + ConvToStr(port);
+ }
this->SetFd(irc::sockets::OpenTCPSocket(bind_addr.c_str()));
if (this->GetFd() > -1)
diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp
index 7e3b62671..7c5f7ee49 100644
--- a/src/modules/extra/m_ssl_gnutls.cpp
+++ b/src/modules/extra/m_ssl_gnutls.cpp
@@ -30,17 +30,6 @@
enum issl_status { ISSL_NONE, ISSL_HANDSHAKING_READ, ISSL_HANDSHAKING_WRITE, ISSL_HANDSHAKEN, ISSL_CLOSING, ISSL_CLOSED };
-bool isin(const std::string &host, int port, const std::vector<std::string> &portlist)
-{
- if (std::find(portlist.begin(), portlist.end(), "*:" + ConvToStr(port)) != portlist.end())
- return true;
-
- if (std::find(portlist.begin(), portlist.end(), ":" + ConvToStr(port)) != portlist.end())
- return true;
-
- return std::find(portlist.begin(), portlist.end(), host + ":" + ConvToStr(port)) != portlist.end();
-}
-
/** Represents an SSL user's extra data
*/
class issl_session : public classbase
@@ -93,7 +82,7 @@ class CommandStartTLS : public Command
class ModuleSSLGnuTLS : public Module
{
- std::vector<std::string> listenports;
+ std::set<ListenSocketBase*> listenports;
issl_session* sessions;
@@ -107,7 +96,6 @@ class ModuleSSLGnuTLS : public Module
std::string sslports;
int dh_bits;
- int clientactive;
bool cred_alloc;
CommandStartTLS starttls;
@@ -131,8 +119,8 @@ class ModuleSSLGnuTLS : public Module
gnutls_certificate_set_dh_params(x509_cred, dh_params);
Implementation eventlist[] = { I_On005Numeric, I_OnRawSocketConnect, I_OnRawSocketAccept,
I_OnRawSocketClose, I_OnRawSocketRead, I_OnRawSocketWrite, I_OnCleanup,
- I_OnBufferFlushed, I_OnRequest, I_OnUnloadModule, I_OnRehash, I_OnModuleRehash,
- I_OnPostConnect, I_OnEvent, I_OnHookIO };
+ I_OnBufferFlushed, I_OnRequest, I_OnRehash, I_OnModuleRehash, I_OnPostConnect,
+ I_OnEvent, I_OnHookIO };
ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
ServerInstance->AddCommand(&starttls);
@@ -143,51 +131,21 @@ class ModuleSSLGnuTLS : public Module
ConfigReader Conf(ServerInstance);
listenports.clear();
- clientactive = 0;
sslports.clear();
- for(int index = 0; index < Conf.Enumerate("bind"); index++)
+ for (size_t i = 0; i < ServerInstance->ports.size(); i++)
{
- // For each <bind> tag
- std::string x = Conf.ReadValue("bind", "type", index);
- if(((x.empty()) || (x == "clients")) && (Conf.ReadValue("bind", "ssl", index) == "gnutls"))
- {
- // Get the port we're meant to be listening on with SSL
- std::string port = Conf.ReadValue("bind", "port", index);
- std::string addr = Conf.ReadValue("bind", "address", index);
-
- if (!addr.empty())
- {
- // normalize address, important for IPv6
- int portint = 0;
- irc::sockets::sockaddrs bin;
- if (irc::sockets::aptosa(addr.c_str(), portint, &bin))
- irc::sockets::satoap(&bin, addr, portint);
- }
-
- irc::portparser portrange(port, false);
- long portno = -1;
- while ((portno = portrange.GetToken()))
- {
- clientactive++;
- try
- {
- listenports.push_back(addr + ":" + ConvToStr(portno));
+ ListenSocketBase* port = ServerInstance->ports[i];
+ std::string desc = port->GetDescription();
+ if (desc != "gnutls")
+ continue;
- for (size_t i = 0; i < ServerInstance->ports.size(); i++)
- if ((ServerInstance->ports[i]->GetPort() == portno) && (ServerInstance->ports[i]->GetIP() == addr))
- ServerInstance->ports[i]->SetDescription("ssl");
- ServerInstance->Logs->Log("m_ssl_gnutls",DEFAULT, "m_ssl_gnutls.so: Enabling SSL for port %ld", portno);
+ listenports.insert(port);
+ std::string portid = port->GetBindDesc();
- if (addr != "127.0.0.1")
- sslports.append((addr.empty() ? "*" : addr)).append(":").append(ConvToStr(portno)).append(";");
- }
- catch (ModuleException &e)
- {
- ServerInstance->Logs->Log("m_ssl_gnutls",DEFAULT, "m_ssl_gnutls.so: FAILED to enable SSL on port %ld: %s. Maybe it's already hooked by the same port on a different IP, or you have an other SSL or similar module loaded?", portno, e.GetReason());
- }
- }
- }
+ ServerInstance->Logs->Log("m_ssl_gnutls", DEFAULT, "m_ssl_gnutls.so: Enabling SSL for port %s", portid.c_str());
+ if (port->GetIP() != "127.0.0.1")
+ sslports.append(portid).append(";");
}
if (!sslports.empty())
@@ -320,19 +278,6 @@ class ModuleSSLGnuTLS : public Module
}
}
- virtual void OnUnloadModule(Module* mod, const std::string &name)
- {
- if(mod == this)
- {
- for(unsigned int i = 0; i < listenports.size(); i++)
- {
- for (size_t j = 0; j < ServerInstance->ports.size(); j++)
- if (listenports[i] == (ServerInstance->ports[j]->GetIP()+":"+ConvToStr(ServerInstance->ports[j]->GetPort())))
- ServerInstance->ports[j]->SetDescription("plaintext");
- }
- }
- }
-
virtual Version GetVersion()
{
return Version("$Id$", VF_VENDOR, API_VERSION);
@@ -348,7 +293,7 @@ class ModuleSSLGnuTLS : public Module
virtual void OnHookIO(EventHandler* user, ListenSocketBase* lsb)
{
- if (!user->GetIOHook() && isin(lsb->GetIP(),lsb->GetPort(),listenports))
+ if (!user->GetIOHook() && listenports.find(lsb) != listenports.end())
{
/* Hook the user with our module */
user->AddIOHook(this);
diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp
index fc0de61f4..a8043457b 100644
--- a/src/modules/extra/m_ssl_openssl.cpp
+++ b/src/modules/extra/m_ssl_openssl.cpp
@@ -40,17 +40,6 @@ enum issl_io_status { ISSL_WRITE, ISSL_READ };
static bool SelfSigned = false;
-bool isin(const std::string &host, int port, const std::vector<std::string> &portlist)
-{
- if (std::find(portlist.begin(), portlist.end(), "*:" + ConvToStr(port)) != portlist.end())
- return true;
-
- if (std::find(portlist.begin(), portlist.end(), ":" + ConvToStr(port)) != portlist.end())
- return true;
-
- return std::find(portlist.begin(), portlist.end(), host + ":" + ConvToStr(port)) != portlist.end();
-}
-
char* get_error()
{
return ERR_error_string(ERR_get_error(), NULL);
@@ -98,7 +87,7 @@ static int OnVerify(int preverify_ok, X509_STORE_CTX *ctx)
class ModuleSSLOpenSSL : public Module
{
- std::vector<std::string> listenports;
+ std::set<ListenSocketBase*> listenports;
int inbufsize;
issl_session* sessions;
@@ -116,8 +105,6 @@ class ModuleSSLOpenSSL : public Module
std::string dhfile;
std::string sslports;
- int clientactive;
-
public:
InspIRCd* PublicInstance;
@@ -152,14 +139,14 @@ class ModuleSSLOpenSSL : public Module
OnModuleRehash(NULL,"ssl");
Implementation eventlist[] = { I_OnRawSocketConnect, I_OnRawSocketAccept,
I_OnRawSocketClose, I_OnRawSocketRead, I_OnRawSocketWrite, I_OnCleanup, I_On005Numeric,
- I_OnBufferFlushed, I_OnRequest, I_OnUnloadModule, I_OnRehash, I_OnModuleRehash,
- I_OnPostConnect, I_OnHookIO };
+ I_OnBufferFlushed, I_OnRequest, I_OnRehash, I_OnModuleRehash, I_OnPostConnect,
+ I_OnHookIO };
ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
}
virtual void OnHookIO(EventHandler* user, ListenSocketBase* lsb)
{
- if (!user->GetIOHook() && isin(lsb->GetIP(),lsb->GetPort(),listenports))
+ if (!user->GetIOHook() && listenports.find(lsb) != listenports.end())
{
/* Hook the user with our module */
user->AddIOHook(this);
@@ -171,51 +158,21 @@ class ModuleSSLOpenSSL : public Module
ConfigReader Conf(ServerInstance);
listenports.clear();
- clientactive = 0;
sslports.clear();
- for(int index = 0; index < Conf.Enumerate("bind"); index++)
+ for (size_t i = 0; i < ServerInstance->ports.size(); i++)
{
- // For each <bind> tag
- std::string x = Conf.ReadValue("bind", "type", index);
- if(((x.empty()) || (x == "clients")) && (Conf.ReadValue("bind", "ssl", index) == "openssl"))
- {
- // Get the port we're meant to be listening on with SSL
- std::string port = Conf.ReadValue("bind", "port", index);
- std::string addr = Conf.ReadValue("bind", "address", index);
-
- if (!addr.empty())
- {
- // normalize address, important for IPv6
- int portint = 0;
- irc::sockets::sockaddrs bin;
- if (irc::sockets::aptosa(addr.c_str(), portint, &bin))
- irc::sockets::satoap(&bin, addr, portint);
- }
-
- irc::portparser portrange(port, false);
- long portno = -1;
- while ((portno = portrange.GetToken()))
- {
- clientactive++;
- try
- {
- listenports.push_back(addr + ":" + ConvToStr(portno));
+ ListenSocketBase* port = ServerInstance->ports[i];
+ std::string desc = port->GetDescription();
+ if (desc != "openssl")
+ continue;
- for (size_t i = 0; i < ServerInstance->ports.size(); i++)
- if ((ServerInstance->ports[i]->GetPort() == portno) && (ServerInstance->ports[i]->GetIP() == addr))
- ServerInstance->ports[i]->SetDescription("ssl");
- ServerInstance->Logs->Log("m_ssl_openssl",DEFAULT, "m_ssl_openssl.so: Enabling SSL for port %ld", portno);
+ listenports.insert(port);
+ std::string portid = port->GetBindDesc();
- if (addr != "127.0.0.1")
- sslports.append((addr.empty() ? "*" : addr)).append(":").append(ConvToStr(portno)).append(";");
- }
- catch (ModuleException &e)
- {
- ServerInstance->Logs->Log("m_ssl_openssl",DEFAULT, "m_ssl_openssl.so: FAILED to enable SSL on port %ld: %s. Maybe it's already hooked by the same port on a different IP, or you have an other SSL or similar module loaded?", portno, e.GetReason());
- }
- }
- }
+ ServerInstance->Logs->Log("m_ssl_openssl", DEFAULT, "m_ssl_openssl.so: Enabling SSL for port %s", portid.c_str());
+ if (port->GetIP() != "127.0.0.1")
+ sslports.append(portid).append(";");
}
if (!sslports.empty())
@@ -311,7 +268,8 @@ class ModuleSSLOpenSSL : public Module
virtual void On005Numeric(std::string &output)
{
- output.append(" SSL=" + sslports);
+ if (!sslports.empty())
+ output.append(" SSL=" + sslports);
}
virtual ~ModuleSSLOpenSSL()
@@ -345,19 +303,6 @@ class ModuleSSLOpenSSL : public Module
}
}
- virtual void OnUnloadModule(Module* mod, const std::string &name)
- {
- if (mod == this)
- {
- for(unsigned int i = 0; i < listenports.size(); i++)
- {
- for (size_t j = 0; j < ServerInstance->ports.size(); j++)
- if (listenports[i] == (ServerInstance->ports[j]->GetIP()+":"+ConvToStr(ServerInstance->ports[j]->GetPort())))
- ServerInstance->ports[j]->SetDescription("plaintext");
- }
- }
- }
-
virtual Version GetVersion()
{
return Version("$Id$", VF_VENDOR, API_VERSION);
diff --git a/src/socket.cpp b/src/socket.cpp
index 2eb8aeb7e..e32bda901 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -126,7 +126,7 @@ int irc::sockets::OpenTCPSocket(const char* addr, int socktype)
// XXX: it would be VERY nice to genericize this so all listen stuff (server/client) could use the one function. -- w00t
int InspIRCd::BindPorts(FailedPortList &failed_ports)
{
- char configToken[MAXBUF], Addr[MAXBUF], Type[MAXBUF];
+ char configToken[MAXBUF], Addr[MAXBUF], Type[MAXBUF], Desc[MAXBUF];
int bound = 0;
bool started_with_nothing = (ports.size() == 0);
std::vector<std::pair<std::string, int> > old_ports;
@@ -140,6 +140,7 @@ int InspIRCd::BindPorts(FailedPortList &failed_ports)
Config->ConfValue("bind", "port", count, configToken, MAXBUF);
Config->ConfValue("bind", "address", count, Addr, MAXBUF);
Config->ConfValue("bind", "type", count, Type, MAXBUF);
+ Config->ConfValue("bind", "ssl", count, Desc, MAXBUF);
if (strncmp(Addr, "::ffff:", 7) == 0)
this->Logs->Log("SOCKET",DEFAULT, "Using 4in6 (::ffff:) isn't recommended. You should bind IPv4 addresses directly instead.");
@@ -176,6 +177,7 @@ int InspIRCd::BindPorts(FailedPortList &failed_ports)
if (ll->GetFd() > -1)
{
bound++;
+ ll->SetDescription(*Desc ? Desc : "plaintext");
ports.push_back(ll);
}
else