summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/core/db_mysql.cpp2
-rw-r--r--modules/core/os_restart.cpp2
-rw-r--r--modules/core/os_shutdown.cpp2
-rw-r--r--modules/extra/m_ssl.cpp152
-rw-r--r--modules/extra/m_xmlrpc.cpp37
-rw-r--r--modules/protocol/bahamut.cpp2
-rw-r--r--modules/protocol/inspircd-ts6.h2
-rw-r--r--modules/protocol/inspircd11.cpp2
-rw-r--r--modules/protocol/plexus.cpp2
-rw-r--r--modules/protocol/ratbox.cpp2
-rw-r--r--modules/protocol/unreal.cpp2
11 files changed, 114 insertions, 93 deletions
diff --git a/modules/core/db_mysql.cpp b/modules/core/db_mysql.cpp
index 193d467da..6a5ba8900 100644
--- a/modules/core/db_mysql.cpp
+++ b/modules/core/db_mysql.cpp
@@ -136,7 +136,7 @@ class DBMySQL : public Module
if (operserv)
this->AddCommand(operserv->Bot(), &commandsqlsync);
- if (uplink_server)
+ if (CurrentUplink)
OnServerConnect();
}
diff --git a/modules/core/os_restart.cpp b/modules/core/os_restart.cpp
index bda2d861c..196d0a3ab 100644
--- a/modules/core/os_restart.cpp
+++ b/modules/core/os_restart.cpp
@@ -26,7 +26,7 @@ class CommandOSRestart : public Command
{
User *u = source.u;
quitmsg = "RESTART command received from " + u->nick;
- do_restart_services();
+ quitting = save_data = restarting = true;
return MOD_CONT;
}
diff --git a/modules/core/os_shutdown.cpp b/modules/core/os_shutdown.cpp
index c67d7acb2..35f76f0c9 100644
--- a/modules/core/os_shutdown.cpp
+++ b/modules/core/os_shutdown.cpp
@@ -26,7 +26,7 @@ class CommandOSShutdown : public Command
{
User *u = source.u;
quitmsg = "SHUTDOWN command received from " + u->nick;
- shutting_down = true;
+ quitting = save_data = true;
return MOD_CONT;
}
diff --git a/modules/extra/m_ssl.cpp b/modules/extra/m_ssl.cpp
index da6361769..30e548150 100644
--- a/modules/extra/m_ssl.cpp
+++ b/modules/extra/m_ssl.cpp
@@ -28,9 +28,16 @@ class MySSLService : public SSLService
class SSLSocketIO : public SocketIO
{
+ /** Check whether this socket has a pending connect() or accept()
+ * @return 0 if neither, -1 if connect/accept fails, -2 to wait more
+ */
+ int CheckState();
+
public:
/* The SSL socket for this socket */
SSL *sslsock;
+ /* -1 if not, 0 if waiting, 1 if true */
+ int connected, accepted;
/** Constructor
*/
@@ -42,27 +49,27 @@ class SSLSocketIO : public SocketIO
* @param sz How much to read
* @return Number of bytes received
*/
- int Recv(Socket *s, char *buf, size_t sz) const;
+ int Recv(Socket *s, char *buf, size_t sz);
/** Really write something to the socket
* @param s The socket
* @param buf What to write
* @return Number of bytes written
*/
- int Send(Socket *s, const Anope::string &buf) const;
+ int Send(Socket *s, const Anope::string &buf);
/** Accept a connection from a socket
* @param s The socket
+ * @return The new socket
*/
- void Accept(ListenSocket *s);
+ ClientSocket *Accept(ListenSocket *s);
/** Connect the socket
* @param s THe socket
* @param target IP to connect to
* @param port to connect to
- * @param bindip IP to bind to, if any
*/
- void Connect(ConnectionSocket *s, const Anope::string &target, int port, const Anope::string &bindip = "");
+ void Connect(ConnectionSocket *s, const Anope::string &target, int port);
/** Called when the socket is destructing
*/
@@ -144,41 +151,27 @@ class SSLModule : public Module
~SSLModule()
{
+ for (std::map<int, Socket *>::const_iterator it = SocketEngine::Sockets.begin(), it_end = SocketEngine::Sockets.end(); it != it_end;)
+ {
+ Socket *s = it->second;
+ ++it;
+
+ if (dynamic_cast<SSLSocketIO *>(s->IO))
+ delete s;
+ }
+
SSL_CTX_free(client_ctx);
SSL_CTX_free(server_ctx);
}
- EventReturn OnPreServerConnect(Uplink *u, int Number)
+ void OnPreServerConnect()
{
ConfigReader config;
- if (config.ReadFlag("uplink", "ssl", "no", Number - 1))
+ if (config.ReadFlag("uplink", "ssl", "no", CurrentUplink))
{
- DNSRecord req = DNSManager::BlockingQuery(uplink_server->host, uplink_server->ipv6 ? DNS_QUERY_AAAA : DNS_QUERY_A);
-
- if (!req)
- Log() << "Unable to connect to server " << uplink_server->host << ":" << uplink_server->port << " using SSL: Invalid hostname/IP";
- else
- {
- try
- {
- new UplinkSocket(uplink_server->ipv6);
- this->service.Init(UplinkSock);
- UplinkSock->Connect(req.result, uplink_server->port, Config->LocalHost);
-
- Log() << "Connected to server " << Number << " (" << u->host << ":" << u->port << ") with SSL";
- return EVENT_ALLOW;
- }
- catch (const SocketException &ex)
- {
- Log() << "Unable to connect with SSL to server " << Number << " (" << u->host << ":" << u->port << "), " << ex.GetReason();
- }
- }
-
- return EVENT_STOP;
+ this->service.Init(UplinkSock);
}
-
- return EVENT_CONTINUE;
}
};
@@ -194,39 +187,67 @@ void MySSLService::Init(Socket *s)
s->IO = new SSLSocketIO();
}
-SSLSocketIO::SSLSocketIO()
+int SSLSocketIO::CheckState()
+{
+ if (this->connected == 0 || this->accepted == 0)
+ {
+ int ret;
+ if (this->connected == 0)
+ ret = SSL_connect(this->sslsock);
+ else if (this->accepted == 0)
+ ret = SSL_accept(this->sslsock);
+ if (ret <= 0)
+ {
+ int error = SSL_get_error(this->sslsock, ret);
+
+ if (ret == -1 && (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE))
+ // Wait more
+ return -2;
+ return -1;
+ }
+
+ if (this->connected == 0)
+ this->connected = 1;
+ else if (this->accepted == 0)
+ this->accepted = 1;
+ }
+
+ return 0;
+}
+
+SSLSocketIO::SSLSocketIO() : connected(-1), accepted(-1)
{
this->sslsock = NULL;
}
-int SSLSocketIO::Recv(Socket *s, char *buf, size_t sz) const
+int SSLSocketIO::Recv(Socket *s, char *buf, size_t sz)
{
- int i = SSL_read(this->sslsock, buf, sz);
+ int i = this->CheckState();
+ if (i < 0)
+ return i;
+
+ i = SSL_read(this->sslsock, buf, sz);
TotalRead += i;
return i;
}
-int SSLSocketIO::Send(Socket *s, const Anope::string &buf) const
+int SSLSocketIO::Send(Socket *s, const Anope::string &buf)
{
- int i = SSL_write(this->sslsock, buf.c_str(), buf.length());
+ int i = this->CheckState();
+ if (i < 0)
+ return i;
+
+ i = SSL_write(this->sslsock, buf.c_str(), buf.length());
TotalWritten += i;
return i;
}
-void SSLSocketIO::Accept(ListenSocket *s)
+ClientSocket *SSLSocketIO::Accept(ListenSocket *s)
{
- sockaddrs conaddr;
-
- socklen_t size = conaddr.size();
- int newsock = accept(s->GetFD(), &conaddr.sa, &size);
-
-#ifndef INVALID_SOCKET
-# define INVALID_SOCKET -1
-#endif
- if (newsock <= 0 || newsock == INVALID_SOCKET)
- throw SocketException("Unable to accept SSL socket: " + Anope::LastError());
-
- ClientSocket *newsocket = s->OnAccept(newsock, conaddr);
+ if (s->IO == &normalSocketIO)
+ throw SocketException("Attempting to accept on uninitialized socket with SSL");
+
+ ClientSocket *newsocket = normalSocketIO.Accept(s);
me->service.Init(newsocket);
SSLSocketIO *IO = debug_cast<SSLSocketIO *>(newsocket->IO);
@@ -236,25 +257,22 @@ void SSLSocketIO::Accept(ListenSocket *s)
SSL_set_accept_state(IO->sslsock);
- if (!SSL_set_fd(IO->sslsock, newsock))
+ if (!SSL_set_fd(IO->sslsock, newsocket->GetFD()))
throw SocketException("Unable to set SSL fd");
- int ret = SSL_accept(IO->sslsock);
- if (ret <= 0)
- {
- int error = SSL_get_error(IO->sslsock, ret);
-
- if (ret != -1 || (error != SSL_ERROR_WANT_READ && error != SSL_ERROR_WANT_READ))
- throw SocketException("Unable to accept new SSL connection: " + Anope::string(ERR_error_string(ERR_get_error(), NULL)));
- }
+ IO->accepted = 0;
+ if (this->CheckState() == -1)
+ throw SocketException("Unable to accept new SSL connection: " + Anope::string(ERR_error_string(ERR_get_error(), NULL)));
+
+ return newsocket;
}
-void SSLSocketIO::Connect(ConnectionSocket *s, const Anope::string &TargetHost, int Port, const Anope::string &BindHost)
+void SSLSocketIO::Connect(ConnectionSocket *s, const Anope::string &target, int port)
{
if (s->IO == &normalSocketIO)
- throw SocketException("Attempting to connect uninitialized socket with SQL");
+ throw SocketException("Attempting to connect uninitialized socket with SSL");
- normalSocketIO.Connect(s, TargetHost, Port, BindHost);
+ normalSocketIO.Connect(s, target, port);
SSLSocketIO *IO = debug_cast<SSLSocketIO *>(s->IO);
@@ -265,15 +283,9 @@ void SSLSocketIO::Connect(ConnectionSocket *s, const Anope::string &TargetHost,
if (!SSL_set_fd(IO->sslsock, s->GetFD()))
throw SocketException("Unable to set SSL fd");
- int ret = SSL_connect(IO->sslsock);
-
- if (ret <= 0)
- {
- int error = SSL_get_error(IO->sslsock, ret);
-
- if (ret != -1 || (error != SSL_ERROR_WANT_READ && error != SSL_ERROR_WANT_READ))
- throw SocketException("Unable to connect to server: " + Anope::string(ERR_error_string(ERR_get_error(), NULL)));
- }
+ IO->connected = 0;
+ if (this->CheckState() == -1)
+ throw SocketException("Unable to connect to server: " + Anope::string(ERR_error_string(ERR_get_error(), NULL)));
}
void SSLSocketIO::Destroy()
diff --git a/modules/extra/m_xmlrpc.cpp b/modules/extra/m_xmlrpc.cpp
index 8c0723c42..bba72c2f5 100644
--- a/modules/extra/m_xmlrpc.cpp
+++ b/modules/extra/m_xmlrpc.cpp
@@ -2,6 +2,8 @@
#include "ssl.h"
#include "xmlrpc.h"
+std::vector<XMLRPCListenSocket *> listen_sockets;
+
class MyXMLRPCClientSocket : public XMLRPCClientSocket
{
/* Used to skip the (optional) HTTP header, which we really don't care about */
@@ -85,7 +87,17 @@ class MyXMLRPCClientSocket : public XMLRPCClientSocket
class MyXMLRPCListenSocket : public XMLRPCListenSocket
{
public:
- MyXMLRPCListenSocket(const Anope::string &bindip, int port, bool ipv6, const Anope::string &u, const Anope::string &p, const std::vector<Anope::string> &a) : XMLRPCListenSocket(bindip, port, ipv6, u, p, a) { }
+ MyXMLRPCListenSocket(const Anope::string &bindip, int port, bool ipv6, const Anope::string &u, const Anope::string &p, const std::vector<Anope::string> &a) : XMLRPCListenSocket(bindip, port, ipv6, u, p, a)
+ {
+ listen_sockets.push_back(this);
+ }
+
+ ~MyXMLRPCListenSocket()
+ {
+ std::vector<XMLRPCListenSocket *>::iterator it = std::find(listen_sockets.begin(), listen_sockets.end(), this);
+ if (it != listen_sockets.end())
+ listen_sockets.erase(it);
+ }
ClientSocket *OnAccept(int fd, const sockaddrs &addr)
{
@@ -208,7 +220,6 @@ class ModuleXMLRPC;
static ModuleXMLRPC *me;
class ModuleXMLRPC : public Module
{
- std::vector<MyXMLRPCListenSocket *> listen_sockets;
service_reference<SSLService> sslref;
public:
@@ -229,15 +240,16 @@ class ModuleXMLRPC : public Module
~ModuleXMLRPC()
{
/* Clean up our sockets and our listening sockets */
- for (std::map<int, Socket *>::const_iterator it = SocketEngine::Sockets.begin(), it_end = SocketEngine::Sockets.end(); it != it_end; ++it)
+ for (std::map<int, Socket *>::const_iterator it = SocketEngine::Sockets.begin(), it_end = SocketEngine::Sockets.end(); it != it_end;)
{
Socket *s = it->second;
+ ++it;
if (s->Type == SOCKTYPE_CLIENT)
{
ClientSocket *cs = debug_cast<ClientSocket *>(s);
- for (unsigned i = 0; i < this->listen_sockets.size(); ++i)
- if (cs->LS == this->listen_sockets[i])
+ for (unsigned i = 0; i < listen_sockets.size(); ++i)
+ if (cs->LS == listen_sockets[i])
{
delete cs;
break;
@@ -245,18 +257,18 @@ class ModuleXMLRPC : public Module
}
}
- for (unsigned i = 0; i < this->listen_sockets.size(); ++i)
- delete this->listen_sockets[i];
- this->listen_sockets.clear();
+ for (unsigned i = 0; i < listen_sockets.size(); ++i)
+ delete listen_sockets[i];
+ listen_sockets.clear();
}
void OnReload()
{
ConfigReader config;
- for (unsigned i = 0; i < this->listen_sockets.size(); ++i)
- delete this->listen_sockets[i];
- this->listen_sockets.clear();
+ for (unsigned i = 0; i < listen_sockets.size(); ++i)
+ delete listen_sockets[i];
+ listen_sockets.clear();
for (int i = 0; i < config.Enumerate("m_xmlrpc"); ++i)
{
@@ -282,10 +294,7 @@ class ModuleXMLRPC : public Module
{
MyXMLRPCListenSocket *xmls = new MyXMLRPCListenSocket(bindip, port, ipv6, username, password, allowed_vector);
if (ssl)
- {
sslref->Init(xmls);
- }
- this->listen_sockets.push_back(xmls);
}
catch (const SocketException &ex)
{
diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp
index 92aee74fb..29f16004e 100644
--- a/modules/protocol/bahamut.cpp
+++ b/modules/protocol/bahamut.cpp
@@ -232,7 +232,7 @@ class BahamutIRCdProto : public IRCDProto
void SendConnect()
{
- bahamut_cmd_pass(uplink_server->password);
+ bahamut_cmd_pass(Config->Uplinks[CurrentUplink]->password);
bahamut_cmd_capab();
SendServer(Me);
bahamut_cmd_svinfo();
diff --git a/modules/protocol/inspircd-ts6.h b/modules/protocol/inspircd-ts6.h
index d76dc27c2..cf93865f8 100644
--- a/modules/protocol/inspircd-ts6.h
+++ b/modules/protocol/inspircd-ts6.h
@@ -124,7 +124,7 @@ class InspIRCdTS6Proto : public IRCDProto
/* SERVER services-dev.chatspike.net password 0 :Description here */
void SendServer(const Server *server)
{
- send_cmd("", "SERVER %s %s %d %s :%s", server->GetName().c_str(), uplink_server ? uplink_server->password.c_str() : "none", server->GetHops(), server->GetSID().c_str(), server->GetDescription().c_str());
+ send_cmd("", "SERVER %s %s %d %s :%s", server->GetName().c_str(), Config->Uplinks[CurrentUplink]->password.c_str(), server->GetHops(), server->GetSID().c_str(), server->GetDescription().c_str());
}
/* JOIN */
diff --git a/modules/protocol/inspircd11.cpp b/modules/protocol/inspircd11.cpp
index 5ab55ab07..a382d4006 100644
--- a/modules/protocol/inspircd11.cpp
+++ b/modules/protocol/inspircd11.cpp
@@ -199,7 +199,7 @@ class InspIRCdProto : public IRCDProto
void SendConnect()
{
- inspircd_cmd_pass(uplink_server->password);
+ inspircd_cmd_pass(Config->Uplinks[CurrentUplink]->password);
SendServer(Me);
send_cmd("", "BURST");
Module *enc = ModuleManager::FindFirstOf(ENCRYPTION);
diff --git a/modules/protocol/plexus.cpp b/modules/protocol/plexus.cpp
index 04095e5a2..5e6c67781 100644
--- a/modules/protocol/plexus.cpp
+++ b/modules/protocol/plexus.cpp
@@ -157,7 +157,7 @@ class PlexusProto : public IRCDProto
void SendConnect()
{
- plexus_cmd_pass(uplink_server->password);
+ plexus_cmd_pass(Config->Uplinks[CurrentUplink]->password);
plexus_cmd_capab();
/* Make myself known to myself in the serverlist */
SendServer(Me);
diff --git a/modules/protocol/ratbox.cpp b/modules/protocol/ratbox.cpp
index d6cfc761f..2833c52b7 100644
--- a/modules/protocol/ratbox.cpp
+++ b/modules/protocol/ratbox.cpp
@@ -160,7 +160,7 @@ class RatboxProto : public IRCDProto
void SendConnect()
{
- ratbox_cmd_pass(uplink_server->password);
+ ratbox_cmd_pass(Config->Uplinks[CurrentUplink]->password);
ratbox_cmd_capab();
/* Make myself known to myself in the serverlist */
SendServer(Me);
diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp
index cb7a54d61..e07b97af0 100644
--- a/modules/protocol/unreal.cpp
+++ b/modules/protocol/unreal.cpp
@@ -228,7 +228,7 @@ class UnrealIRCdProto : public IRCDProto
void SendConnect()
{
unreal_cmd_capab();
- unreal_cmd_pass(uplink_server->password);
+ unreal_cmd_pass(Config->Uplinks[CurrentUplink]->password);
SendServer(Me);
}