diff options
author | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2009-09-21 13:26:31 +0000 |
---|---|---|
committer | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2009-09-21 13:26:31 +0000 |
commit | e2af2347fc035d702e45f12e772223a8d578410d (patch) | |
tree | bfd80aac2858a9f4faedc316794fc1051dbaa72c /src | |
parent | 16fc672b685752007e47aed0fb97bc1ee7443c76 (diff) |
Create StreamSocket for IO hooking implementation
Fixes the SSL SendQ bug
Removes duplicate code between User and BufferedSocket
Simplify SSL module API
Simplify EventHandler API (Readable/Writeable moved to SE)
Add hook for culled objects to invoke callbacks prior to destructor
Replace SocketCull with GlobalCull now that sockets can close themselves
Shorten common case of user read/parse/write path:
User::Write is now zero-copy up to syscall/SSL invocation
User::Read has only two copy/scan passes from read() to ProcessCommand
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11752 e03df62e-2008-0410-955e-edbf42e46eb7
Diffstat (limited to 'src')
68 files changed, 825 insertions, 1489 deletions
diff --git a/src/base.cpp b/src/base.cpp index 27eb4af23..2b022688d 100644 --- a/src/base.cpp +++ b/src/base.cpp @@ -26,6 +26,14 @@ classbase::classbase() { } +void classbase::cull() +{ +} + +classbase::~classbase() +{ +} + void BoolSet::Set(int number) { this->bits |= bitfields[number]; diff --git a/src/command_parse.cpp b/src/command_parse.cpp index 92d4b8c24..cbf6a1005 100644 --- a/src/command_parse.cpp +++ b/src/command_parse.cpp @@ -226,23 +226,6 @@ CmdResult CommandParser::CallHandler(const std::string &commandname, const std:: return CMD_INVALID; } -void CommandParser::DoLines(User* current, bool one_only) -{ - while (current->BufferIsReady()) - { - // use GetBuffer to copy single lines into the sanitized string - std::string single_line = current->GetBuffer(); - current->bytes_in += single_line.length(); - current->cmds_in++; - if (single_line.length() > MAXBUF - 2) // MAXBUF is 514 to allow for neccessary line terminators - single_line.resize(MAXBUF - 2); // So to trim to 512 here, we use MAXBUF - 2 - - // ProcessBuffer returns false if the user has gone over penalty - if (!ServerInstance->Parser->ProcessBuffer(single_line, current) || one_only) - break; - } -} - bool CommandParser::ProcessCommand(User *user, std::string &cmd) { std::vector<std::string> command_p; @@ -435,23 +418,12 @@ void CommandParser::RemoveCommand(Commandtable::iterator safei, Module* source) bool CommandParser::ProcessBuffer(std::string &buffer,User *user) { - std::string::size_type a; - - if (!user) + if (!user || buffer.empty()) return true; - while ((a = buffer.rfind("\n")) != std::string::npos) - buffer.erase(a); - while ((a = buffer.rfind("\r")) != std::string::npos) - buffer.erase(a); - - if (buffer.length()) - { - ServerInstance->Logs->Log("USERINPUT", DEBUG,"C[%d] I :%s %s",user->GetFd(), user->nick.c_str(), buffer.c_str()); - return this->ProcessCommand(user,buffer); - } - - return true; + ServerInstance->Logs->Log("USERINPUT", DEBUG, "C[%d] I :%s %s", + user->GetFd(), user->nick.c_str(), buffer.c_str()); + return ProcessCommand(user,buffer); } bool CommandParser::CreateCommand(Command *f) diff --git a/src/cull_list.cpp b/src/cull_list.cpp index 79c077ead..35fa44bfa 100644 --- a/src/cull_list.cpp +++ b/src/cull_list.cpp @@ -18,8 +18,12 @@ void CullList::Apply() { - for(std::vector<classbase*>::iterator i = list.begin(); i != list.end(); i++) - delete *i; + for(std::set<classbase*>::iterator i = list.begin(); i != list.end(); i++) + { + classbase* c = *i; + c->cull(); + delete c; + } list.clear(); } diff --git a/src/helperfuncs.cpp b/src/helperfuncs.cpp index 0ec8db966..80feae464 100644 --- a/src/helperfuncs.cpp +++ b/src/helperfuncs.cpp @@ -125,20 +125,16 @@ void InspIRCd::SendError(const std::string &s) { for (std::vector<User*>::const_iterator i = this->Users->local_users.begin(); i != this->Users->local_users.end(); i++) { - if ((*i)->registered == REG_ALL) + User* u = *i; + if (u->registered == REG_ALL) { - (*i)->WriteServ("NOTICE %s :%s",(*i)->nick.c_str(),s.c_str()); + u->WriteServ("NOTICE %s :%s",u->nick.c_str(),s.c_str()); } else { /* Unregistered connections receive ERROR, not a NOTICE */ - (*i)->Write("ERROR :" + s); + u->Write("ERROR :" + s); } - /* This might generate a whole load of EAGAIN, but we dont really - * care about this, as if we call SendError something catastrophic - * has occured anyway, and we wont receive the events for these. - */ - (*i)->FlushWriteBuf(); } } diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 1b23bff02..704fec475 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -110,7 +110,6 @@ void InspIRCd::Cleanup() { User* u = *i++; Users->QuitUser(u, "Server shutdown"); - u->CloseSocket(); } /* We do this more than once, so that any service providers get a @@ -323,7 +322,6 @@ InspIRCd::InspIRCd(int argc, char** argv) : * THIS MUST MATCH ORDER OF DECLARATION OF THE HandleWhateverFunc classes * within class InspIRCd. */ - HandleProcessUser(this), HandleIsNick(this), HandleIsIdent(this), HandleFloodQuitUser(this), @@ -336,7 +334,6 @@ InspIRCd::InspIRCd(int argc, char** argv) : * THIS MUST MATCH THE ORDER OF DECLARATION OF THE FUNCTORS, e.g. the methods * themselves within the class. */ - ProcessUser(&HandleProcessUser), IsChannel(&HandleIsChannel), IsSID(&HandleIsSID), Rehash(&HandleRehash), @@ -387,9 +384,8 @@ InspIRCd::InspIRCd(int argc, char** argv) : // This must be created first, so other parts of Insp can use it while starting up this->Logs = new LogManager(this); - SocketEngineFactory* SEF = new SocketEngineFactory(); - SE = SEF->Create(this); - delete SEF; + SocketEngineFactory SEF; + SE = SEF.Create(); this->Threads = new ThreadEngine(this); @@ -832,9 +828,6 @@ int InspIRCd::Run() /* if any users were quit, take them out */ this->GlobalCulls.Apply(); - /* If any inspsockets closed, remove them */ - this->BufferedSocketCull(); - if (this->s_signal) { this->SignalHandler(s_signal); @@ -845,18 +838,6 @@ int InspIRCd::Run() return 0; } -void InspIRCd::BufferedSocketCull() -{ - for (std::map<BufferedSocket*,BufferedSocket*>::iterator x = SocketCull.begin(); x != SocketCull.end(); ++x) - { - this->Logs->Log("MISC",DEBUG,"Cull socket"); - SE->DelFd(x->second); - x->second->Close(); - delete x->second; - } - SocketCull.clear(); -} - /**********************************************************************************/ /** diff --git a/src/inspsocket.cpp b/src/inspsocket.cpp index 0350858e7..964582062 100644 --- a/src/inspsocket.cpp +++ b/src/inspsocket.cpp @@ -16,195 +16,100 @@ #include "inspstring.h" #include "socketengine.h" -bool BufferedSocket::Readable() +BufferedSocket::BufferedSocket() { - return (this->state != I_CONNECTING); + Timeout = NULL; + state = I_ERROR; } -BufferedSocket::BufferedSocket(InspIRCd* SI) +BufferedSocket::BufferedSocket(int newfd) { - this->Timeout = NULL; - this->state = I_DISCONNECTED; - this->fd = -1; - this->ServerInstance = SI; -} - -BufferedSocket::BufferedSocket(InspIRCd* SI, int newfd, const char* ip) -{ - this->Timeout = NULL; + Timeout = NULL; this->fd = newfd; this->state = I_CONNECTED; - strlcpy(this->IP,ip,MAXBUF); - this->ServerInstance = SI; - if (this->fd > -1) - this->ServerInstance->SE->AddFd(this); + if (fd > -1) + ServerInstance->SE->AddFd(this); } -BufferedSocket::BufferedSocket(InspIRCd* SI, const std::string &ipaddr, int aport, unsigned long maxtime, const std::string &connectbindip) +void BufferedSocket::DoConnect(const std::string &ipaddr, int aport, unsigned long maxtime, const std::string &connectbindip) { - this->cbindip = connectbindip; - this->fd = -1; - this->ServerInstance = SI; - strlcpy(host,ipaddr.c_str(),MAXBUF); - this->Timeout = NULL; - - strlcpy(this->host,ipaddr.c_str(),MAXBUF); - this->port = aport; - - irc::sockets::sockaddrs testaddr; - if (!irc::sockets::aptosa(host, aport, &testaddr)) - { - this->ServerInstance->Logs->Log("SOCKET", DEBUG,"BUG: Hostname passed to BufferedSocket, rather than an IP address!"); - this->OnError(I_ERR_CONNECT); - this->Close(); - this->fd = -1; - this->state = I_ERROR; - return; - } - else + BufferedSocketError err = BeginConnect(ipaddr, aport, maxtime, connectbindip); + if (err != I_ERR_NONE) { - strlcpy(this->IP,host,MAXBUF); - if (!this->DoConnect(maxtime)) - { - this->OnError(I_ERR_CONNECT); - this->Close(); - this->fd = -1; - this->state = I_ERROR; - return; - } + state = I_ERROR; + SetError(strerror(errno)); + OnError(err); } } -void BufferedSocket::SetQueues() +BufferedSocketError BufferedSocket::BeginConnect(const std::string &ipaddr, int aport, unsigned long maxtime, const std::string &connectbindip) { - // attempt to increase socket sendq and recvq as high as its possible - int sendbuf = 32768; - int recvbuf = 32768; - if(setsockopt(this->fd,SOL_SOCKET,SO_SNDBUF,(const char *)&sendbuf,sizeof(sendbuf)) || setsockopt(this->fd,SOL_SOCKET,SO_RCVBUF,(const char *)&recvbuf,sizeof(sendbuf))) + irc::sockets::sockaddrs addr, bind; + if (!irc::sockets::aptosa(ipaddr.c_str(), aport, &addr)) { - //this->ServerInstance->Log(DEFAULT, "Could not increase SO_SNDBUF/SO_RCVBUF for socket %u", GetFd()); - ; // do nothing. I'm a little sick of people trying to interpret this message as a result of why their incorrect setups don't work. + ServerInstance->Logs->Log("SOCKET", DEBUG, "BUG: Hostname passed to BufferedSocket, rather than an IP address!"); + return I_ERR_CONNECT; } -} -bool BufferedSocket::DoBindMagic(const std::string ¤t_ip) -{ - irc::sockets::sockaddrs s; - if (!irc::sockets::aptosa(current_ip.c_str(), 0, &s)) + bind.sa.sa_family = 0; + if (!connectbindip.empty()) { - errno = EADDRNOTAVAIL; - return false; - } - - if (ServerInstance->SE->Bind(this->fd, &s.sa, sa_size(s)) < 0) - { - this->state = I_ERROR; - this->OnError(I_ERR_BIND); - return false; + if (!irc::sockets::aptosa(connectbindip.c_str(), 0, &bind)) + { + return I_ERR_BIND; + } } - return true; + return BeginConnect(addr, bind, maxtime); } -/* Most irc servers require you to specify the ip you want to bind to. - * If you dont specify an IP, they rather dumbly bind to the first IP - * of the box (e.g. INADDR_ANY). In InspIRCd, we scan thought the IP - * addresses we've bound server ports to, and we try and bind our outbound - * connections to the first usable non-loopback and non-any IP we find. - * This is easier to configure when you have a lot of links and a lot - * of servers to configure. - */ -bool BufferedSocket::BindAddr(const std::string &ip_to_bind) +static void IncreaseOSBuffers(int fd) { - ConfigReader Conf(this->ServerInstance); - - // Case one: If they provided an IP, try bind it - if (!ip_to_bind.empty()) - { - // And if it fails, don't do anything. - return this->DoBindMagic(ip_to_bind); - } - - for (int j = 0; j < Conf.Enumerate("bind"); j++) - { - // We only want to try bind to a server ip. - if (Conf.ReadValue("bind","type",j) != "servers") - continue; - - // set current IP to the <bind> tag - std::string current_ip = Conf.ReadValue("bind","address",j); - - // Make sure IP is nothing local - if (current_ip == "*" || current_ip == "127.0.0.1" || current_ip.empty() || current_ip == "::1") - continue; - - // Try bind, don't fail if it doesn't bind though. - if (this->DoBindMagic(current_ip)) - return true; - } - - // NOTE: You may wonder WTF we are returning *true* here, but that is because there were no custom binds setup, and so we have nothing to do - // (remember, outgoing connections without binding are perfectly ok). - ServerInstance->Logs->Log("SOCKET", DEBUG,"nothing in the config to bind()!"); - return true; + // attempt to increase socket sendq and recvq as high as its possible + int sendbuf = 32768; + int recvbuf = 32768; + setsockopt(fd,SOL_SOCKET,SO_SNDBUF,(const char *)&sendbuf,sizeof(sendbuf)); + setsockopt(fd,SOL_SOCKET,SO_RCVBUF,(const char *)&recvbuf,sizeof(recvbuf)); + // on failure, do nothing. I'm a little sick of people trying to interpret this message as a result of why their incorrect setups don't work. } -bool BufferedSocket::DoConnect(unsigned long maxtime) +BufferedSocketError BufferedSocket::BeginConnect(const irc::sockets::sockaddrs& dest, const irc::sockets::sockaddrs& bind, unsigned long timeout) { - irc::sockets::sockaddrs addr; - irc::sockets::aptosa(this->host, this->port, &addr); - - this->fd = socket(addr.sa.sa_family, SOCK_STREAM, 0); + if (fd < 0) + fd = socket(dest.sa.sa_family, SOCK_STREAM, 0); - if (this->fd == -1) - { - this->state = I_ERROR; - this->OnError(I_ERR_SOCKET); - return false; - } + if (fd < 0) + return I_ERR_SOCKET; - if (!this->BindAddr(this->cbindip)) + if (bind.sa.sa_family != 0) { - this->Close(); - this->fd = -1; - return false; + if (ServerInstance->SE->Bind(fd, &bind.sa, sa_size(bind)) < 0) + return I_ERR_BIND; } - ServerInstance->SE->NonBlocking(this->fd); + ServerInstance->SE->NonBlocking(fd); - if (ServerInstance->SE->Connect(this, &addr.sa, sa_size(addr)) == -1) + if (ServerInstance->SE->Connect(this, &dest.sa, sa_size(dest)) == -1) { if (errno != EINPROGRESS) - { - this->OnError(I_ERR_CONNECT); - this->Close(); - this->state = I_ERROR; - return false; - } - - this->Timeout = new SocketTimeout(this->GetFd(), this->ServerInstance, this, maxtime, this->ServerInstance->Time()); - this->ServerInstance->Timers->AddTimer(this->Timeout); + return I_ERR_CONNECT; } this->state = I_CONNECTING; - if (this->fd > -1) - { - if (!this->ServerInstance->SE->AddFd(this)) - { - this->OnError(I_ERR_NOMOREFDS); - this->Close(); - this->state = I_ERROR; - return false; - } - this->SetQueues(); - } + + if (!ServerInstance->SE->AddFd(this, true)) + return I_ERR_NOMOREFDS; + + this->Timeout = new SocketTimeout(this->GetFd(), this, timeout, ServerInstance->Time()); + ServerInstance->Timers->AddTimer(this->Timeout); + + IncreaseOSBuffers(fd); ServerInstance->Logs->Log("SOCKET", DEBUG,"BufferedSocket::DoConnect success"); - return true; + return I_ERR_NONE; } - -void BufferedSocket::Close() +void StreamSocket::Close() { /* Save this, so we dont lose it, * otherise on failure, error messages @@ -213,190 +118,196 @@ void BufferedSocket::Close() int save = errno; if (this->fd > -1) { - if (this->GetIOHook()) + if (IOHook) { try { - this->GetIOHook()->OnRawSocketClose(this->fd); + IOHook->OnStreamSocketClose(this); } catch (CoreException& modexcept) { - ServerInstance->Logs->Log("SOCKET", DEFAULT,"%s threw an exception: %s", modexcept.GetSource(), modexcept.GetReason()); + ServerInstance->Logs->Log("SOCKET", DEFAULT,"%s threw an exception: %s", + modexcept.GetSource(), modexcept.GetReason()); } } ServerInstance->SE->Shutdown(this, 2); - if (ServerInstance->SE->Close(this) != -1) - this->OnClose(); - - if (ServerInstance->SocketCull.find(this) == ServerInstance->SocketCull.end()) - ServerInstance->SocketCull[this] = this; + ServerInstance->SE->DelFd(this); + ServerInstance->SE->Close(this); + fd = -1; } errno = save; } -std::string BufferedSocket::GetIP() +void StreamSocket::cull() { - return this->IP; + Close(); } -const char* BufferedSocket::Read() +bool StreamSocket::GetNextLine(std::string& line, char delim) { - if (!ServerInstance->SE->BoundsCheckFd(this)) - return NULL; - - int n = 0; - char* ReadBuffer = ServerInstance->GetReadBuffer(); + std::string::size_type i = recvq.find(delim); + if (i == std::string::npos) + return false; + line = recvq.substr(0, i - 1); + // TODO is this the most efficient way to split? + recvq = recvq.substr(i + 1); + return true; +} - if (this->GetIOHook()) +void StreamSocket::DoRead() +{ + if (IOHook) { - int result2 = 0; - int MOD_RESULT = 0; + int rv = -1; try { - MOD_RESULT = this->GetIOHook()->OnRawSocketRead(this->fd, ReadBuffer, ServerInstance->Config->NetBufferSize, result2); + rv = IOHook->OnStreamSocketRead(this, recvq); } catch (CoreException& modexcept) { - ServerInstance->Logs->Log("SOCKET", DEFAULT,"%s threw an exception: %s", modexcept.GetSource(), modexcept.GetReason()); + ServerInstance->Logs->Log("SOCKET", DEFAULT, "%s threw an exception: %s", + modexcept.GetSource(), modexcept.GetReason()); + return; } - if (MOD_RESULT < 0) + if (rv > 0) + OnDataReady(); + if (rv < 0) + SetError("Read Error"); // will not overwrite a better error message + } + else + { + char* ReadBuffer = ServerInstance->GetReadBuffer(); + int n = recv(fd, ReadBuffer, ServerInstance->Config->NetBufferSize, 0); + if (n > 0) { - n = -1; - errno = EAGAIN; + recvq.append(ReadBuffer, n); + OnDataReady(); } - else + else if (n == 0) { - n = result2; + error = "Connection closed"; + } + else if (errno != EAGAIN && errno != EINTR) + { + error = strerror(errno); } - } - else - { - n = recv(this->fd, ReadBuffer, ServerInstance->Config->NetBufferSize, 0); - } - - /* - * This used to do some silly bounds checking instead of just passing bufsize - 1 to recv. - * Not only does that make absolutely no sense, but it could potentially result in a read buffer's worth - * of data being thrown into the bit bucket for no good reason, which is just *stupid*.. do things correctly now. - * --w00t (july 2, 2008) - */ - if (n > 0) - { - ReadBuffer[n] = 0; - return ReadBuffer; - } - else - { - int err = errno; - if (err == EAGAIN) - return ""; - else - return NULL; } } -/* - * This function formerly tried to flush write buffer each call. - * While admirable in attempting to get the data out to wherever - * it is going, on a full socket, it's just going to syscall write() and - * EAGAIN constantly, instead of waiting in the SE to know if it can write - * which will chew a bit of CPU. - * - * So, now this function returns void (take note) and just adds to the sendq. - * - * It'll get written at a determinate point when the socketengine tells us it can write. - * -- w00t (april 1, 2008) - */ -void BufferedSocket::Write(const std::string &data) +void StreamSocket::DoWrite() { - /* Append the data to the back of the queue ready for writing */ - outbuffer.push_back(data); - - /* Mark ourselves as wanting write */ - this->ServerInstance->SE->WantWrite(this); -} + if (sendq.empty()) + return; -bool BufferedSocket::FlushWriteBuffer() -{ - errno = 0; - if ((this->fd > -1) && (this->state == I_CONNECTED)) + if (IOHook) { - if (this->GetIOHook()) + int rv = -1; + try { - while (outbuffer.size() && (errno != EAGAIN)) + while (!sendq.empty()) { - try + std::string& front = sendq.front(); + int itemlen = front.length(); + rv = IOHook->OnStreamSocketWrite(this, front); + if (rv > 0) + { + // consumed the entire string, and is ready for more + sendq_len -= itemlen; + sendq.pop_front(); + } + else if (rv == 0) { - /* XXX: The lack of buffering here is NOT a bug, modules implementing this interface have to - * implement their own buffering mechanisms - */ - this->GetIOHook()->OnRawSocketWrite(this->fd, outbuffer[0].c_str(), outbuffer[0].length()); - outbuffer.pop_front(); + // socket has blocked. Stop trying to send data. + // IOHook has requested unblock notification from the socketengine + + // Since it is possible that a partial write took place, adjust sendq_len + sendq_len = sendq_len - itemlen + front.length(); + return; } - catch (CoreException& modexcept) + else { - ServerInstance->Logs->Log("SOCKET", DEBUG,"%s threw an exception: %s", modexcept.GetSource(), modexcept.GetReason()); - return true; + SetError("Write Error"); // will not overwrite a better error message + return; } } } - else + catch (CoreException& modexcept) { - /* If we have multiple lines, try to send them all, - * not just the first one -- Brain - */ - while (outbuffer.size() && (errno != EAGAIN)) + ServerInstance->Logs->Log("SOCKET", DEBUG,"%s threw an exception: %s", + modexcept.GetSource(), modexcept.GetReason()); + } + } + else + { + // Prepare a writev() call to write all buffers efficiently + int bufcount = sendq.size(); + + // cap the number of buffers at IOV_MAX + if (bufcount > IOV_MAX) + bufcount = IOV_MAX; + + iovec* iovecs = new iovec[bufcount]; + for(int i=0; i < bufcount; i++) + { + iovecs[i].iov_base = const_cast<char*>(sendq[i].data()); + iovecs[i].iov_len = sendq[i].length(); + } + int rv = writev(fd, iovecs, bufcount); + delete[] iovecs; + if (rv == (int)sendq_len) + { + // it's our lucky day, everything got written out. Fast cleanup. + sendq_len = 0; + sendq.clear(); + } + else if (rv > 0) + { + // Partial write. Clean out strings from the sendq + sendq_len -= rv; + while (rv > 0 && !sendq.empty()) { - /* Send a line */ - int result = ServerInstance->SE->Send(this, outbuffer[0].c_str(), outbuffer[0].length(), 0); - - if (result > 0) + std::string& front = sendq.front(); + if (front.length() < (size_t)rv) { - if ((unsigned int)result >= outbuffer[0].length()) - { - /* The whole block was written (usually a line) - * Pop the block off the front of the queue, - * dont set errno, because we are clear of errors - * and want to try and write the next block too. - */ - outbuffer.pop_front(); - } - else - { - std::string temp = outbuffer[0].substr(result); - outbuffer[0] = temp; - /* We didnt get the whole line out. arses. - * Try again next time, i guess. Set errno, - * because we shouldnt be writing any more now, - * until the socketengine says its safe to do so. - */ - errno = EAGAIN; - } + // this string got fully written out + rv -= front.length(); + sendq.pop_front(); } - else if (result == 0) + else { - this->ServerInstance->SE->DelFd(this); - this->Close(); - return true; - } - else if ((result == -1) && (errno != EAGAIN)) - { - this->OnError(I_ERR_WRITE); - this->state = I_ERROR; - this->ServerInstance->SE->DelFd(this); - this->Close(); - return true; + // stopped in the middle of this string + front = front.substr(rv); + rv = 0; } } } + else if (rv == 0) + { + error = "Connection closed"; + } + else if (errno != EAGAIN && errno != EINTR) + { + error = strerror(errno); + } + if (sendq_len && error.empty()) + ServerInstance->SE->WantWrite(this); } +} + +void StreamSocket::WriteData(const std::string &data) +{ + bool newWrite = sendq.empty() && !data.empty(); - if ((errno == EAGAIN) && (fd > -1)) + /* Append the data to the back of the queue ready for writing */ + sendq.push_back(data); + sendq_len += data.length(); + + if (newWrite) { - this->ServerInstance->SE->WantWrite(this); + // TODO perhaps we should try writing first, before asking SE about writes? + // DoWrite(); + ServerInstance->SE->WantWrite(this); } - - return (fd < 0); } void SocketTimeout::Tick(time_t) @@ -421,57 +332,26 @@ void SocketTimeout::Tick(time_t) */ this->sock->state = I_ERROR; - if (ServerInstance->SocketCull.find(this->sock) == ServerInstance->SocketCull.end()) - ServerInstance->SocketCull[this->sock] = this->sock; + ServerInstance->GlobalCulls.AddItem(sock); } this->sock->Timeout = NULL; } -bool BufferedSocket::InternalMarkConnected() -{ - /* Our socket was in write-state, so delete it and re-add it - * in read-state. - */ - this->SetState(I_CONNECTED); +void BufferedSocket::OnConnected() { } +void BufferedSocket::OnTimeout() { return; } - if (this->GetIOHook()) +void BufferedSocket::DoWrite() +{ + if (state == I_CONNECTING) { - ServerInstance->Logs->Log("SOCKET",DEBUG,"Hook for raw connect"); - try - { - this->GetIOHook()->OnRawSocketConnect(this->fd); - } - catch (CoreException& modexcept) - { - ServerInstance->Logs->Log("SOCKET",DEBUG,"%s threw an exception: %s", modexcept.GetSource(), modexcept.GetReason()); - return false; - } + state = I_CONNECTED; + this->OnConnected(); + if (GetIOHook()) + GetIOHook()->OnStreamSocketConnect(this); } - return this->OnConnected(); -} - -void BufferedSocket::SetState(BufferedSocketState s) -{ - this->state = s; -} - -BufferedSocketState BufferedSocket::GetState() -{ - return this->state; -} - -bool BufferedSocket::OnConnected() { return true; } -void BufferedSocket::OnError(BufferedSocketError) { return; } -int BufferedSocket::OnDisconnect() { return 0; } -bool BufferedSocket::OnDataReady() { return true; } -bool BufferedSocket::OnWriteReady() -{ - // Default behaviour: just try write some. - return !this->FlushWriteBuffer(); + this->StreamSocket::DoWrite(); } -void BufferedSocket::OnTimeout() { return; } -void BufferedSocket::OnClose() { return; } BufferedSocket::~BufferedSocket() { @@ -483,68 +363,49 @@ BufferedSocket::~BufferedSocket() } } -void BufferedSocket::HandleEvent(EventType et, int errornum) +void StreamSocket::HandleEvent(EventType et, int errornum) { + BufferedSocketError errcode = I_ERR_OTHER; switch (et) { case EVENT_ERROR: { + SetError(strerror(errornum)); switch (errornum) { case ETIMEDOUT: - this->OnError(I_ERR_TIMEOUT); + errcode = I_ERR_TIMEOUT; break; case ECONNREFUSED: case 0: - this->OnError(this->state == I_CONNECTING ? I_ERR_CONNECT : I_ERR_WRITE); + errcode = I_ERR_CONNECT; break; case EADDRINUSE: - this->OnError(I_ERR_BIND); + errcode = I_ERR_BIND; break; case EPIPE: case EIO: - this->OnError(I_ERR_WRITE); + errcode = I_ERR_WRITE; break; } - - if (this->ServerInstance->SocketCull.find(this) == this->ServerInstance->SocketCull.end()) - this->ServerInstance->SocketCull[this] = this; - return; break; } case EVENT_READ: { - if (!this->OnDataReady()) - { - if (this->ServerInstance->SocketCull.find(this) == this->ServerInstance->SocketCull.end()) - this->ServerInstance->SocketCull[this] = this; - return; - } + DoRead(); break; } case EVENT_WRITE: { - if (this->state == I_CONNECTING) - { - if (!this->InternalMarkConnected()) - { - if (this->ServerInstance->SocketCull.find(this) == this->ServerInstance->SocketCull.end()) - this->ServerInstance->SocketCull[this] = this; - return; - } - return; - } - else - { - if (!this->OnWriteReady()) - { - if (this->ServerInstance->SocketCull.find(this) == this->ServerInstance->SocketCull.end()) - this->ServerInstance->SocketCull[this] = this; - return; - } - } + DoWrite(); break; } } + if (!error.empty()) + { + ServerInstance->Logs->Log("SOCKET", DEBUG, "Error on FD %d - '%s'", fd, error.c_str()); + OnError(errcode); + ServerInstance->GlobalCulls.AddItem(this); + } } diff --git a/src/modules.cpp b/src/modules.cpp index 51fecb47c..c11b63bec 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -159,11 +159,11 @@ void Module::OnGlobalOper(User*) { } void Module::OnPostConnect(User*) { } ModResult Module::OnAddBan(User*, Channel*, const std::string &) { return MOD_RES_PASSTHRU; } ModResult Module::OnDelBan(User*, Channel*, const std::string &) { return MOD_RES_PASSTHRU; } -void Module::OnRawSocketAccept(int, irc::sockets::sockaddrs*, irc::sockets::sockaddrs*) { } -int Module::OnRawSocketWrite(int, const char*, int) { return 0; } -void Module::OnRawSocketClose(int) { } -void Module::OnRawSocketConnect(int) { } -int Module::OnRawSocketRead(int, char*, unsigned int, int&) { return 0; } +void Module::OnStreamSocketAccept(StreamSocket*, irc::sockets::sockaddrs*, irc::sockets::sockaddrs*) { } +int Module::OnStreamSocketWrite(StreamSocket*, std::string&) { return -1; } +void Module::OnStreamSocketClose(StreamSocket*) { } +void Module::OnStreamSocketConnect(StreamSocket*) { } +int Module::OnStreamSocketRead(StreamSocket*, std::string&) { return -1; } void Module::OnUserMessage(User*, void*, int, const std::string&, char, const CUList&) { } void Module::OnUserNotice(User*, void*, int, const std::string&, char, const CUList&) { } void Module::OnRemoteKill(User*, User*, const std::string&, const std::string&) { } @@ -196,7 +196,7 @@ void Module::OnText(User*, void*, int, const std::string&, char, CUList&) { } void Module::OnRunTestSuite() { } void Module::OnNamesListItem(User*, Membership*, std::string&, std::string&) { } ModResult Module::OnNumeric(User*, unsigned int, const std::string&) { return MOD_RES_PASSTHRU; } -void Module::OnHookIO(EventHandler*, ListenSocketBase*) { } +void Module::OnHookIO(StreamSocket*, ListenSocketBase*) { } ModResult Module::OnHostCycle(User*) { return MOD_RES_PASSTHRU; } void Module::OnSendWhoLine(User*, User*, Channel*, std::string&) { } diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index f458f5da1..27c466573 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -56,7 +56,6 @@ public: gnutls_session_t sess; issl_status status; - std::string outbuf; }; class CommandStartTLS : public Command @@ -83,7 +82,7 @@ class CommandStartTLS : public Command { user->WriteNumeric(670, "%s :STARTTLS successful, go ahead with TLS handshake", user->nick.c_str()); user->AddIOHook(creator); - creator->OnRawSocketAccept(user->GetFd(), NULL, NULL); + creator->OnStreamSocketAccept(user, NULL, NULL); } else user->WriteNumeric(691, "%s :STARTTLS failure", user->nick.c_str()); @@ -133,16 +132,14 @@ class ModuleSSLGnuTLS : public Module // Void return, guess we assume success 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_OnRehash, I_OnModuleRehash, I_OnPostConnect, + Implementation eventlist[] = { I_On005Numeric, I_OnRequest, I_OnRehash, I_OnModuleRehash, I_OnPostConnect, I_OnEvent, I_OnHookIO }; ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation)); ServerInstance->AddCommand(&starttls); } - virtual void OnRehash(User* user) + void OnRehash(User* user) { ConfigReader Conf(ServerInstance); @@ -168,7 +165,7 @@ class ModuleSSLGnuTLS : public Module sslports.erase(sslports.end() - 1); } - virtual void OnModuleRehash(User* user, const std::string ¶m) + void OnModuleRehash(User* user, const std::string ¶m) { if(param != "ssl") return; @@ -278,7 +275,7 @@ class ModuleSSLGnuTLS : public Module ServerInstance->Logs->Log("m_ssl_gnutls",DEFAULT, "m_ssl_gnutls.so: Failed to generate DH parameters (%d bits): %s", dh_bits, gnutls_strerror(ret)); } - virtual ~ModuleSSLGnuTLS() + ~ModuleSSLGnuTLS() { gnutls_x509_crt_deinit(x509_cert); gnutls_x509_privkey_deinit(x509_key); @@ -289,7 +286,7 @@ class ModuleSSLGnuTLS : public Module delete[] sessions; } - virtual void OnCleanup(int target_type, void* item) + void OnCleanup(int target_type, void* item) { if(target_type == TYPE_USER) { @@ -305,20 +302,20 @@ class ModuleSSLGnuTLS : public Module } } - virtual Version GetVersion() + Version GetVersion() { return Version("$Id$", VF_VENDOR, API_VERSION); } - virtual void On005Numeric(std::string &output) + void On005Numeric(std::string &output) { if (!sslports.empty()) output.append(" SSL=" + sslports); output.append(" STARTTLS"); } - virtual void OnHookIO(EventHandler* user, ListenSocketBase* lsb) + void OnHookIO(StreamSocket* user, ListenSocketBase* lsb) { if (!user->GetIOHook() && listenports.find(lsb) != listenports.end()) { @@ -327,7 +324,7 @@ class ModuleSSLGnuTLS : public Module } } - virtual const char* OnRequest(Request* request) + const char* OnRequest(Request* request) { ISHRequest* ISR = static_cast<ISHRequest*>(request); if (strcmp("IS_NAME", request->GetId()) == 0) @@ -336,20 +333,13 @@ class ModuleSSLGnuTLS : public Module } else if (strcmp("IS_HOOK", request->GetId()) == 0) { - const char* ret = "OK"; - try - { - ret = ISR->Sock->AddIOHook(this) ? "OK" : NULL; - } - catch (ModuleException &e) - { - return NULL; - } - return ret; + ISR->Sock->AddIOHook(this); + return "OK"; } else if (strcmp("IS_UNHOOK", request->GetId()) == 0) { - return ISR->Sock->DelIOHook() ? "OK" : NULL; + ISR->Sock->DelIOHook(); + return "OK"; } else if (strcmp("IS_HSDONE", request->GetId()) == 0) { @@ -383,12 +373,9 @@ class ModuleSSLGnuTLS : public Module } - virtual void OnRawSocketAccept(int fd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server) + void OnStreamSocketAccept(StreamSocket* user, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server) { - /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */ - if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1)) - return; - + int fd = user->GetFd(); issl_session* session = &sessions[fd]; /* For STARTTLS: Don't try and init a session on a socket that already has a session */ @@ -405,77 +392,67 @@ class ModuleSSLGnuTLS : public Module gnutls_certificate_server_set_request(session->sess, GNUTLS_CERT_REQUEST); // Request client certificate if any. - Handshake(session, fd); + Handshake(session, user); } - virtual void OnRawSocketConnect(int fd) + void OnStreamSocketConnect(StreamSocket* user) { - /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */ - if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1)) - return; - - issl_session* session = &sessions[fd]; + issl_session* session = &sessions[user->GetFd()]; gnutls_init(&session->sess, GNUTLS_CLIENT); gnutls_set_default_priority(session->sess); // Avoid calling all the priority functions, defaults are adequate. gnutls_credentials_set(session->sess, GNUTLS_CRD_CERTIFICATE, x509_cred); gnutls_dh_set_prime_bits(session->sess, dh_bits); - gnutls_transport_set_ptr(session->sess, reinterpret_cast<gnutls_transport_ptr_t>(fd)); // Give gnutls the fd for the socket. + gnutls_transport_set_ptr(session->sess, reinterpret_cast<gnutls_transport_ptr_t>(user->GetFd())); - Handshake(session, fd); + Handshake(session, user); } - virtual void OnRawSocketClose(int fd) + void OnStreamSocketClose(StreamSocket* user) { - /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */ - if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds())) - return; - - CloseSession(&sessions[fd]); + CloseSession(&sessions[user->GetFd()]); } - virtual int OnRawSocketRead(int fd, char* buffer, unsigned int count, int &readresult) + int OnStreamSocketRead(StreamSocket* user, std::string& recvq) { - /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */ - if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1)) - return 0; - - issl_session* session = &sessions[fd]; + issl_session* session = &sessions[user->GetFd()]; if (!session->sess) { - readresult = 0; CloseSession(session); - return 1; + user->SetError("No SSL session"); + return -1; } if (session->status == ISSL_HANDSHAKING_READ) { // The handshake isn't finished, try to finish it. - if(!Handshake(session, fd)) + if(!Handshake(session, user)) { - errno = session->status == ISSL_CLOSING ? EIO : EAGAIN; - // Couldn't resume handshake. + if (session->status != ISSL_CLOSING) + return 0; + user->SetError("Handshake Failed"); return -1; } } else if (session->status == ISSL_HANDSHAKING_WRITE) { - errno = EAGAIN; - MakePollWrite(fd); - return -1; + MakePollWrite(user); + return 0; } // If we resumed the handshake then session->status will be ISSL_HANDSHAKEN. if (session->status == ISSL_HANDSHAKEN) { - unsigned int len = 0; - while (len < count) + char* buffer = ServerInstance->GetReadBuffer(); + size_t bufsiz = ServerInstance->Config->NetBufferSize; + size_t len = 0; + while (len < bufsiz) { - int ret = gnutls_record_recv(session->sess, buffer + len, count - len); + int ret = gnutls_record_recv(session->sess, buffer + len, bufsiz - len); if (ret > 0) { len += ret; @@ -484,60 +461,49 @@ class ModuleSSLGnuTLS : public Module { break; } + else if (ret == 0) + { + user->SetError("SSL Connection closed"); + CloseSession(session); + return -1; + } else { - if (ret != 0) - ServerInstance->Logs->Log("m_ssl_gnutls", DEFAULT, - "m_ssl_gnutls.so: Error while reading on fd %d: %s", - fd, gnutls_strerror(ret)); - - // if ret == 0, client closed connection. - readresult = 0; + user->SetError(gnutls_strerror(ret)); CloseSession(session); - return 1; + return -1; } } - readresult = len; if (len) { + recvq.append(buffer, len); return 1; } - else - { - errno = EAGAIN; - return -1; - } } else if (session->status == ISSL_CLOSING) - readresult = 0; + return -1; - return 1; + return 0; } - virtual int OnRawSocketWrite(int fd, const char* buffer, int count) + int OnStreamSocketWrite(StreamSocket* user, std::string& sendq) { - /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */ - if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1)) - return 0; - - issl_session* session = &sessions[fd]; - const char* sendbuffer = buffer; + issl_session* session = &sessions[user->GetFd()]; if (!session->sess) { CloseSession(session); - return 1; + user->SetError("No SSL session"); + return -1; } - session->outbuf.append(sendbuffer, count); - sendbuffer = session->outbuf.c_str(); - count = session->outbuf.size(); - if (session->status == ISSL_HANDSHAKING_WRITE || session->status == ISSL_HANDSHAKING_READ) { // The handshake isn't finished, try to finish it. - Handshake(session, fd); - errno = session->status == ISSL_CLOSING ? EIO : EAGAIN; + Handshake(session, user); + if (session->status != ISSL_CLOSING) + return 0; + user->SetError("Handshake Failed"); return -1; } @@ -545,42 +511,41 @@ class ModuleSSLGnuTLS : public Module if (session->status == ISSL_HANDSHAKEN) { - ret = gnutls_record_send(session->sess, sendbuffer, count); + ret = gnutls_record_send(session->sess, sendq.data(), sendq.length()); - if (ret == 0) + if (ret == (int)sendq.length()) { - CloseSession(session); + return 1; } - else if (ret < 0) + else if (ret > 0) { - if(ret != GNUTLS_E_AGAIN && ret != GNUTLS_E_INTERRUPTED) - { - ServerInstance->Logs->Log("m_ssl_gnutls", DEFAULT, - "m_ssl_gnutls.so: Error while writing to fd %d: %s", - fd, gnutls_strerror(ret)); - CloseSession(session); - } - else - { - errno = EAGAIN; - } + sendq = sendq.substr(ret); + MakePollWrite(user); + return 0; } - else + else if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED) + { + MakePollWrite(user); + return 0; + } + else if (ret == 0) { - session->outbuf = session->outbuf.substr(ret); + CloseSession(session); + user->SetError("SSL Connection closed"); + return -1; + } + else // (ret < 0) + { + user->SetError(gnutls_strerror(ret)); + CloseSession(session); + return -1; } } - if (!session->outbuf.empty()) - MakePollWrite(fd); - - /* Who's smart idea was it to return 1 when we havent written anything? - * This fucks the buffer up in BufferedSocket :p - */ - return ret < 1 ? 0 : ret; + return 0; } - bool Handshake(issl_session* session, int fd) + bool Handshake(issl_session* session, EventHandler* user) { int ret = gnutls_handshake(session->sess); @@ -599,15 +564,11 @@ class ModuleSSLGnuTLS : public Module { // gnutls_handshake() wants to write() again. session->status = ISSL_HANDSHAKING_WRITE; - MakePollWrite(fd); + MakePollWrite(user); } } else { - // Handshake failed. - ServerInstance->Logs->Log("m_ssl_gnutls", DEFAULT, - "m_ssl_gnutls.so: Handshake failed on fd %d: %s", - fd, gnutls_strerror(ret)); CloseSession(session); session->status = ISSL_CLOSING; } @@ -619,18 +580,16 @@ class ModuleSSLGnuTLS : public Module // Change the seesion state session->status = ISSL_HANDSHAKEN; - EventHandler* user = ServerInstance->SE->GetRef(fd); - VerifyCertificate(session,user); // Finish writing, if any left - MakePollWrite(fd); + MakePollWrite(user); return true; } } - virtual void OnPostConnect(User* user) + void OnPostConnect(User* user) { // This occurs AFTER OnUserConnect so we can be sure the // protocol module has propagated the NICK message. @@ -646,22 +605,9 @@ class ModuleSSLGnuTLS : public Module } } - void MakePollWrite(int fd) + void MakePollWrite(EventHandler* eh) { - //OnRawSocketWrite(fd, NULL, 0); - EventHandler* eh = ServerInstance->SE->GetRef(fd); - if (eh) - ServerInstance->SE->WantWrite(eh); - } - - virtual void OnBufferFlushed(User* user) - { - if (user->GetIOHook() == this) - { - issl_session* session = &sessions[user->GetFd()]; - if (session && session->outbuf.size()) - OnRawSocketWrite(user->GetFd(), NULL, 0); - } + ServerInstance->SE->WantWrite(eh); } void CloseSession(issl_session* session) @@ -672,7 +618,6 @@ class ModuleSSLGnuTLS : public Module gnutls_deinit(session->sess); } - session->outbuf.clear(); session->sess = NULL; session->status = ISSL_NONE; } diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index a33cf6bc2..e77fa23ff 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -59,7 +59,7 @@ public: unsigned int inbufoffset; char* inbuf; // Buffer OpenSSL reads into. - std::string outbuf; // Buffer for outgoing data that OpenSSL will not take. + std::string outbuf; int fd; bool outbound; @@ -95,7 +95,6 @@ class ModuleSSLOpenSSL : public Module SSL_CTX* ctx; SSL_CTX* clictx; - char* dummy; char cipher[MAXBUF]; std::string keyfile; @@ -137,14 +136,13 @@ class ModuleSSLOpenSSL : public Module // Needs the flag as it ignores a plain /rehash OnModuleRehash(NULL,"ssl"); - Implementation eventlist[] = { I_OnRawSocketConnect, I_OnRawSocketAccept, - I_OnRawSocketClose, I_OnRawSocketRead, I_OnRawSocketWrite, I_OnCleanup, I_On005Numeric, - I_OnBufferFlushed, I_OnRequest, I_OnRehash, I_OnModuleRehash, I_OnPostConnect, + Implementation eventlist[] = { + I_On005Numeric, 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) + void OnHookIO(StreamSocket* user, ListenSocketBase* lsb) { if (!user->GetIOHook() && listenports.find(lsb) != listenports.end()) { @@ -153,7 +151,7 @@ class ModuleSSLOpenSSL : public Module } } - virtual void OnRehash(User* user) + void OnRehash(User* user) { ConfigReader Conf(ServerInstance); @@ -179,7 +177,7 @@ class ModuleSSLOpenSSL : public Module sslports.erase(sslports.end() - 1); } - virtual void OnModuleRehash(User* user, const std::string ¶m) + void OnModuleRehash(User* user, const std::string ¶m) { if (param != "ssl") return; @@ -266,13 +264,13 @@ class ModuleSSLOpenSSL : public Module fclose(dhpfile); } - virtual void On005Numeric(std::string &output) + void On005Numeric(std::string &output) { if (!sslports.empty()) output.append(" SSL=" + sslports); } - virtual ~ModuleSSLOpenSSL() + ~ModuleSSLOpenSSL() { SSL_CTX_free(ctx); SSL_CTX_free(clictx); @@ -280,7 +278,7 @@ class ModuleSSLOpenSSL : public Module delete[] sessions; } - virtual void OnCleanup(int target_type, void* item) + void OnCleanup(int target_type, void* item) { if (target_type == TYPE_USER) { @@ -296,13 +294,13 @@ class ModuleSSLOpenSSL : public Module } } - virtual Version GetVersion() + Version GetVersion() { return Version("$Id$", VF_VENDOR, API_VERSION); } - virtual const char* OnRequest(Request* request) + const char* OnRequest(Request* request) { ISHRequest* ISR = (ISHRequest*)request; if (strcmp("IS_NAME", request->GetId()) == 0) @@ -311,21 +309,13 @@ class ModuleSSLOpenSSL : public Module } else if (strcmp("IS_HOOK", request->GetId()) == 0) { - const char* ret = "OK"; - try - { - ret = ISR->Sock->AddIOHook((Module*)this) ? "OK" : NULL; - } - catch (ModuleException &e) - { - return NULL; - } - - return ret; + ISR->Sock->AddIOHook(this); + return "OK"; } else if (strcmp("IS_UNHOOK", request->GetId()) == 0) { - return ISR->Sock->DelIOHook() ? "OK" : NULL; + ISR->Sock->DelIOHook(); + return "OK"; } else if (strcmp("IS_HSDONE", request->GetId()) == 0) { @@ -353,11 +343,9 @@ class ModuleSSLOpenSSL : public Module } - virtual void OnRawSocketAccept(int fd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server) + void OnStreamSocketAccept(StreamSocket* user, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server) { - /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */ - if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1)) - return; + int fd = user->GetFd(); issl_session* session = &sessions[fd]; @@ -377,11 +365,12 @@ class ModuleSSLOpenSSL : public Module return; } - Handshake(session); + Handshake(user, session); } - virtual void OnRawSocketConnect(int fd) + void OnStreamSocketConnect(StreamSocket* user) { + int fd = user->GetFd(); /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */ if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() -1)) return; @@ -404,11 +393,12 @@ class ModuleSSLOpenSSL : public Module return; } - Handshake(session); + Handshake(user, session); } - virtual void OnRawSocketClose(int fd) + void OnStreamSocketClose(StreamSocket* user) { + int fd = user->GetFd(); /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */ if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1)) return; @@ -416,19 +406,19 @@ class ModuleSSLOpenSSL : public Module CloseSession(&sessions[fd]); } - virtual int OnRawSocketRead(int fd, char* buffer, unsigned int count, int &readresult) + int OnStreamSocketRead(StreamSocket* user, std::string& recvq) { + int fd = user->GetFd(); /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */ if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1)) - return 0; + return -1; issl_session* session = &sessions[fd]; if (!session->sess) { - readresult = 0; CloseSession(session); - return 1; + return -1; } if (session->status == ISSL_HANDSHAKING) @@ -436,17 +426,17 @@ class ModuleSSLOpenSSL : public Module if (session->rstat == ISSL_READ || session->wstat == ISSL_READ) { // The handshake isn't finished and it wants to read, try to finish it. - if (!Handshake(session)) + if (!Handshake(user, session)) { // Couldn't resume handshake. - errno = session->status == ISSL_NONE ? EIO : EAGAIN; - return -1; + if (session->status == ISSL_NONE) + return -1; + return 0; } } else { - errno = EAGAIN; - return -1; + return 0; } } @@ -456,51 +446,37 @@ class ModuleSSLOpenSSL : public Module { if (session->wstat == ISSL_READ) { - if(DoWrite(session) == 0) + if(DoWrite(user, session) == 0) return 0; } if (session->rstat == ISSL_READ) { - int ret = DoRead(session); + int ret = DoRead(user, session); if (ret > 0) { - if (count <= session->inbufoffset) - { - memcpy(buffer, session->inbuf, count); - // Move the stuff left in inbuf to the beginning of it - memmove(session->inbuf, session->inbuf + count, (session->inbufoffset - count)); - // Now we need to set session->inbufoffset to the amount of data still waiting to be handed to insp. - session->inbufoffset -= count; - // Insp uses readresult as the count of how much data there is in buffer, so: - readresult = count; - } - else - { - // There's not as much in the inbuf as there is space in the buffer, so just copy the whole thing. - memcpy(buffer, session->inbuf, session->inbufoffset); - - readresult = session->inbufoffset; - // Zero the offset, as there's nothing there.. - session->inbufoffset = 0; - } + recvq.append(session->inbuf, session->inbufoffset); + session->inbufoffset = 0; return 1; } - return ret; + else if (errno == EAGAIN || errno == EINTR) + return 0; + else + return -1; } } - return -1; + return 0; } - virtual int OnRawSocketWrite(int fd, const char* buffer, int count) + int OnStreamSocketWrite(StreamSocket* user, std::string& buffer) { + int fd = user->GetFd(); /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */ if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1)) - return 0; + return -1; - errno = EAGAIN; issl_session* session = &sessions[fd]; if (!session->sess) @@ -509,40 +485,53 @@ class ModuleSSLOpenSSL : public Module return -1; } - session->outbuf.append(buffer, count); - MakePollWrite(session); - if (session->status == ISSL_HANDSHAKING) { // The handshake isn't finished, try to finish it. if (session->rstat == ISSL_WRITE || session->wstat == ISSL_WRITE) { - if (!Handshake(session)) + if (!Handshake(user, session)) { // Couldn't resume handshake. - errno = session->status == ISSL_NONE ? EIO : EAGAIN; - return -1; + if (session->status == ISSL_NONE) + return -1; + return 0; } } } + int rv = 0; + + // don't pull items into the output buffer until they are + // unlikely to block; this allows sendq exceeded to continue + // to work for SSL users. + // TODO better signaling for I/O requests so this isn't needed + if (session->outbuf.empty()) + { + session->outbuf = buffer; + rv = 1; + } + if (session->status == ISSL_OPEN) { if (session->rstat == ISSL_WRITE) { - DoRead(session); + DoRead(user, session); } if (session->wstat == ISSL_WRITE) { - return DoWrite(session); + DoWrite(user, session); } } - return 1; + if (rv == 0 || !session->outbuf.empty()) + ServerInstance->SE->WantWrite(user); + + return rv; } - int DoWrite(issl_session* session) + int DoWrite(StreamSocket* user, issl_session* session) { if (!session->outbuf.size()) return -1; @@ -561,6 +550,7 @@ class ModuleSSLOpenSSL : public Module if (err == SSL_ERROR_WANT_WRITE) { session->wstat = ISSL_WRITE; + ServerInstance->SE->WantWrite(user); return -1; } else if (err == SSL_ERROR_WANT_READ) @@ -581,7 +571,7 @@ class ModuleSSLOpenSSL : public Module } } - int DoRead(issl_session* session) + int DoRead(StreamSocket* user, issl_session* session) { // Is this right? Not sure if the unencrypted data is garaunteed to be the same length. // Read into the inbuffer, offset from the beginning by the amount of data we have that insp hasn't taken yet. @@ -606,7 +596,7 @@ class ModuleSSLOpenSSL : public Module else if (err == SSL_ERROR_WANT_WRITE) { session->rstat = ISSL_WRITE; - MakePollWrite(session); + ServerInstance->SE->WantWrite(user); return -1; } else @@ -627,7 +617,7 @@ class ModuleSSLOpenSSL : public Module } } - bool Handshake(issl_session* session) + bool Handshake(EventHandler* user, issl_session* session) { int ret; @@ -650,7 +640,7 @@ class ModuleSSLOpenSSL : public Module { session->wstat = ISSL_WRITE; session->status = ISSL_HANDSHAKING; - MakePollWrite(session); + ServerInstance->SE->WantWrite(user); return true; } else @@ -669,7 +659,7 @@ class ModuleSSLOpenSSL : public Module session->status = ISSL_OPEN; - MakePollWrite(session); + ServerInstance->SE->WantWrite(user); return true; } @@ -682,34 +672,14 @@ class ModuleSSLOpenSSL : public Module return true; } - virtual void OnPostConnect(User* user) - { - // This occurs AFTER OnUserConnect so we can be sure the - // protocol module has propagated the NICK message. - if ((user->GetIOHook() == this) && (IS_LOCAL(user))) - { - if (sessions[user->GetFd()].sess) - user->WriteServ("NOTICE %s :*** You are connected using SSL cipher \"%s\"", user->nick.c_str(), SSL_get_cipher(sessions[user->GetFd()].sess)); - } - } - - void MakePollWrite(issl_session* session) - { - //OnRawSocketWrite(session->fd, NULL, 0); - EventHandler* eh = ServerInstance->SE->GetRef(session->fd); - if (eh) - { - ServerInstance->SE->WantWrite(eh); - } - } - - virtual void OnBufferFlushed(User* user) + void OnBufferFlushed(User* user) { if (user->GetIOHook() == this) { + std::string dummy; issl_session* session = &sessions[user->GetFd()]; if (session && session->outbuf.size()) - OnRawSocketWrite(user->GetFd(), NULL, 0); + OnStreamSocketWrite(user, dummy); } } diff --git a/src/modules/extra/m_ziplink.cpp b/src/modules/extra/m_ziplink.cpp index c220460bd..7d090d80a 100644 --- a/src/modules/extra/m_ziplink.cpp +++ b/src/modules/extra/m_ziplink.cpp @@ -67,29 +67,29 @@ class ModuleZLib : public Module total_out_compressed = total_in_compressed = 0; total_out_uncompressed = total_in_uncompressed = 0; - Implementation eventlist[] = { I_OnRawSocketConnect, I_OnRawSocketAccept, I_OnRawSocketClose, I_OnRawSocketRead, I_OnRawSocketWrite, I_OnStats, I_OnRequest }; - ServerInstance->Modules->Attach(eventlist, this, 7); + Implementation eventlist[] = { I_OnStats, I_OnRequest }; + ServerInstance->Modules->Attach(eventlist, this, 2); // Allocate a buffer which is used for reading and writing data net_buffer_size = ServerInstance->Config->NetBufferSize; net_buffer = new char[net_buffer_size]; } - virtual ~ModuleZLib() + ~ModuleZLib() { ServerInstance->Modules->UnpublishInterface("BufferedSocketHook", this); delete[] sessions; delete[] net_buffer; } - virtual Version GetVersion() + Version GetVersion() { return Version("$Id$", VF_VENDOR, API_VERSION); } /* Handle BufferedSocketHook API requests */ - virtual const char* OnRequest(Request* request) + const char* OnRequest(Request* request) { ISHRequest* ISR = (ISHRequest*)request; if (strcmp("IS_NAME", request->GetId()) == 0) @@ -99,22 +99,13 @@ class ModuleZLib : public Module } else if (strcmp("IS_HOOK", request->GetId()) == 0) { - /* Attach to an inspsocket */ - const char* ret = "OK"; - try - { - ret = ISR->Sock->AddIOHook((Module*)this) ? "OK" : NULL; - } - catch (ModuleException& e) - { - return NULL; - } - return ret; + ISR->Sock->AddIOHook(this); + return "OK"; } else if (strcmp("IS_UNHOOK", request->GetId()) == 0) { - /* Detach from an inspsocket */ - return ISR->Sock->DelIOHook() ? "OK" : NULL; + ISR->Sock->DelIOHook(); + return "OK"; } else if (strcmp("IS_HSDONE", request->GetId()) == 0) { @@ -134,7 +125,7 @@ class ModuleZLib : public Module } /* Handle stats z (misc stats) */ - virtual ModResult OnStats(char symbol, User* user, string_list &results) + ModResult OnStats(char symbol, User* user, string_list &results) { if (symbol == 'z') { @@ -174,10 +165,14 @@ class ModuleZLib : public Module return MOD_RES_PASSTHRU; } - virtual void OnRawSocketConnect(int fd) + void OnStreamSocketConnect(StreamSocket* user) { - if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1)) - return; + OnStreamSocketAccept(user, 0, 0); + } + + void OnRawSocketAccept(StreamSocket* user, irc::sockets::sockaddrs*, irc::sockets::sockaddrs*) + { + int fd = user->GetFd(); izip_session* session = &sessions[fd]; @@ -211,39 +206,33 @@ class ModuleZLib : public Module session->status = IZIP_OPEN; } - virtual void OnRawSocketAccept(int fd, irc::sockets::sockaddrs*, irc::sockets::sockaddrs*) - { - /* Nothing special needs doing here compared to connect() */ - OnRawSocketConnect(fd); - } - - virtual void OnRawSocketClose(int fd) + void OnStreamSocketClose(StreamSocket* user) { + int fd = user->GetFd(); CloseSession(&sessions[fd]); } - virtual int OnRawSocketRead(int fd, char* buffer, unsigned int count, int &readresult) + int OnStreamSocketRead(StreamSocket* user, std::string& recvq) { + int fd = user->GetFd(); /* Find the sockets session */ izip_session* session = &sessions[fd]; if (session->status == IZIP_CLOSED) - return 0; + return -1; - if (session->inbuf.length()) - { - /* Our input buffer is filling up. This is *BAD*. - * We can't return more data than fits into buffer - * (count bytes), so we will generate another read - * event on purpose by *NOT* reading from 'fd' at all - * for now. - */ - readresult = 0; - } - else + if (session->inbuf.empty()) { /* Read read_buffer_size bytes at a time to the buffer (usually 2.5k) */ - readresult = read(fd, net_buffer, net_buffer_size); + int readresult = read(fd, net_buffer, net_buffer_size); + + if (readresult < 0) + { + if (errno == EINTR || errno == EAGAIN) + return 0; + } + if (readresult <= 0) + return -1; total_in_compressed += readresult; @@ -252,10 +241,8 @@ class ModuleZLib : public Module } size_t in_len = session->inbuf.length(); - - /* Do we have anything to do? */ - if (in_len <= 0) - return 0; + char* buffer = ServerInstance->GetReadBuffer(); + int count = ServerInstance->Config->NetBufferSize; /* Prepare decompression */ session->d_stream.next_in = (Bytef *)session->inbuf.c_str(); @@ -302,8 +289,7 @@ class ModuleZLib : public Module } if (ret != Z_OK) { - readresult = 0; - return 0; + return -1; } /* Update the inbut buffer */ @@ -315,24 +301,18 @@ class ModuleZLib : public Module total_in_uncompressed += uncompressed_length; /* Null-terminate the buffer -- this doesnt harm binary data */ - buffer[uncompressed_length] = 0; - - /* Set the read size to the correct total size */ - readresult = uncompressed_length; - + recvq.append(buffer, uncompressed_length); return 1; } - virtual int OnRawSocketWrite(int fd, const char* buffer, int count) + int OnStreamSocketWrite(StreamSocket* user, std::string& sendq) { + int fd = user->GetFd(); izip_session* session = &sessions[fd]; - if (!count) /* Nothing to do! */ - return 0; - if(session->status != IZIP_OPEN) /* Seriously, wtf? */ - return 0; + return -1; int ret; @@ -343,8 +323,8 @@ class ModuleZLib : public Module do { /* Prepare compression */ - session->c_stream.next_in = (Bytef*)buffer + offset; - session->c_stream.avail_in = count - offset; + session->c_stream.next_in = (Bytef*)sendq.data() + offset; + session->c_stream.avail_in = sendq.length() - offset; session->c_stream.next_out = (Bytef*)net_buffer; session->c_stream.avail_out = net_buffer_size; @@ -378,7 +358,7 @@ class ModuleZLib : public Module /* Space before - space after stuff was added to this */ unsigned int compressed = net_buffer_size - session->c_stream.avail_out; - unsigned int uncompressed = count - session->c_stream.avail_in; + unsigned int uncompressed = sendq.length() - session->c_stream.avail_in; /* Make it skip the data which was compressed already */ offset += uncompressed; @@ -404,14 +384,11 @@ class ModuleZLib : public Module else { session->outbuf.clear(); - return 0; + return -1; } } - /* ALL LIES the lot of it, we havent really written - * this amount, but the layer above doesnt need to know. - */ - return count; + return 1; } void Error(izip_session* session, const std::string &text) diff --git a/src/modules/m_httpd.cpp b/src/modules/m_httpd.cpp index bdf4e424e..c1698accf 100644 --- a/src/modules/m_httpd.cpp +++ b/src/modules/m_httpd.cpp @@ -37,6 +37,7 @@ class HttpServerSocket : public BufferedSocket { FileReader* index; HttpState InternalState; + std::string ip; HTTPHeaders headers; std::string reqbuffer; @@ -48,7 +49,8 @@ class HttpServerSocket : public BufferedSocket public: - HttpServerSocket(InspIRCd* SI, int newfd, const char* ip, FileReader* ind) : BufferedSocket(SI, newfd, ip), index(ind), postsize(0) + HttpServerSocket(int newfd, const char* IP, FileReader* ind) + : BufferedSocket(newfd), index(ind), ip(IP), postsize(0) { InternalState = HTTP_SERVE_WAIT_REQUEST; } @@ -62,7 +64,7 @@ class HttpServerSocket : public BufferedSocket { } - virtual void OnClose() + virtual void OnError(BufferedSocketError) { } @@ -164,15 +166,15 @@ class HttpServerSocket : public BufferedSocket "<small>Powered by <a href='http://www.inspircd.org'>InspIRCd</a></small></body></html>"; SendHeaders(data.length(), response, empty); - this->Write(data); + WriteData(data); } void SendHeaders(unsigned long size, int response, HTTPHeaders &rheaders) { - this->Write(http_version + " "+ConvToStr(response)+" "+Response(response)+"\r\n"); + WriteData(http_version + " "+ConvToStr(response)+" "+Response(response)+"\r\n"); - time_t local = this->ServerInstance->Time(); + time_t local = ServerInstance->Time(); struct tm *timeinfo = gmtime(&local); char *date = asctime(timeinfo); date[strlen(date) - 1] = '\0'; @@ -191,40 +193,32 @@ class HttpServerSocket : public BufferedSocket */ rheaders.SetHeader("Connection", "Close"); - this->Write(rheaders.GetFormattedHeaders()); - this->Write("\r\n"); + WriteData(rheaders.GetFormattedHeaders()); + WriteData("\r\n"); } - virtual bool OnDataReady() + void OnDataReady() { - const char* data = this->Read(); - - /* Check that the data read is a valid pointer and it has some content */ - if (!data || !*data) - return false; - if (InternalState == HTTP_SERVE_RECV_POSTDATA) { - postdata.append(data); + postdata.append(recvq); if (postdata.length() >= postsize) ServeData(); } else { - reqbuffer.append(data); + reqbuffer.append(recvq); if (reqbuffer.length() >= 8192) { ServerInstance->Logs->Log("m_httpd",DEBUG, "m_httpd dropped connection due to an oversized request buffer"); reqbuffer.clear(); - return false; + SetError("Buffer"); } if (InternalState == HTTP_SERVE_WAIT_REQUEST) CheckRequestBuffer(); } - - return true; } void CheckRequestBuffer() @@ -314,18 +308,18 @@ class HttpServerSocket : public BufferedSocket { HTTPHeaders empty; SendHeaders(index->ContentSize(), 200, empty); - this->Write(index->Contents()); + WriteData(index->Contents()); } else { claimed = false; - HTTPRequest httpr(request_type,uri,&headers,this,this->GetIP(),postdata); + HTTPRequest httpr(request_type,uri,&headers,this,ip,postdata); Event acl((char*)&httpr, (Module*)HttpModule, "httpd_acl"); - acl.Send(this->ServerInstance); + acl.Send(ServerInstance); if (!claimed) { Event e((char*)&httpr, (Module*)HttpModule, "httpd_url"); - e.Send(this->ServerInstance); + e.Send(ServerInstance); if (!claimed) { SendHTTPError(404); @@ -337,7 +331,7 @@ class HttpServerSocket : public BufferedSocket void Page(std::stringstream* n, int response, HTTPHeaders *hheaders) { SendHeaders(n->str().length(), response, *hheaders); - this->Write(n->str()); + WriteData(n->str()); } }; @@ -358,7 +352,7 @@ class HttpListener : public ListenSocketBase int port; std::string incomingip; irc::sockets::satoap(&client, incomingip, port); - new HttpServerSocket(ServerInstance, nfd, incomingip.c_str(), index); + new HttpServerSocket(nfd, incomingip.c_str(), index); } }; @@ -426,7 +420,6 @@ class ModuleHttpServer : public Module httpsocks[i]->Close(); delete httpsocks[i]->GetIndex(); } - ServerInstance->BufferedSocketCull(); } virtual Version GetVersion() diff --git a/src/modules/m_spanningtree/addline.cpp b/src/modules/m_spanningtree/addline.cpp index 2f7b5132d..3e6d38070 100644 --- a/src/modules/m_spanningtree/addline.cpp +++ b/src/modules/m_spanningtree/addline.cpp @@ -24,7 +24,7 @@ bool TreeSocket::AddLine(const std::string &prefix, parameterlist ¶ms) { if (params.size() < 6) { - this->ServerInstance->SNO->WriteToSnoMask('d',"%s sent me a malformed ADDLINE of type %s.",prefix.c_str(),params[0].c_str()); + ServerInstance->SNO->WriteToSnoMask('d',"%s sent me a malformed ADDLINE of type %s.",prefix.c_str(),params[0].c_str()); return true; } @@ -43,7 +43,7 @@ bool TreeSocket::AddLine(const std::string &prefix, parameterlist ¶ms) if (!xlf) { - this->ServerInstance->SNO->WriteToSnoMask('d',"%s sent me an unknown ADDLINE type (%s).",setter.c_str(),params[0].c_str()); + ServerInstance->SNO->WriteToSnoMask('d',"%s sent me an unknown ADDLINE type (%s).",setter.c_str(),params[0].c_str()); return true; } @@ -54,7 +54,7 @@ bool TreeSocket::AddLine(const std::string &prefix, parameterlist ¶ms) } catch (ModuleException &e) { - this->ServerInstance->SNO->WriteToSnoMask('d',"Unable to ADDLINE type %s from %s: %s", params[0].c_str(), setter.c_str(), e.GetReason()); + ServerInstance->SNO->WriteToSnoMask('d',"Unable to ADDLINE type %s from %s: %s", params[0].c_str(), setter.c_str(), e.GetReason()); return true; } xl->SetCreateTime(atoi(params[3].c_str())); @@ -62,12 +62,12 @@ bool TreeSocket::AddLine(const std::string &prefix, parameterlist ¶ms) { if (xl->duration) { - this->ServerInstance->SNO->WriteToSnoMask('X',"%s added %s%s on %s to expire on %s: %s",setter.c_str(),params[0].c_str(),params[0].length() == 1 ? "-line" : "", + ServerInstance->SNO->WriteToSnoMask('X',"%s added %s%s on %s to expire on %s: %s",setter.c_str(),params[0].c_str(),params[0].length() == 1 ? "-line" : "", params[1].c_str(),ServerInstance->TimeString(xl->expiry).c_str(),params[5].c_str()); } else { - this->ServerInstance->SNO->WriteToSnoMask('X',"%s added permanent %s%s on %s: %s",setter.c_str(),params[0].c_str(),params[0].length() == 1 ? "-line" : "", + ServerInstance->SNO->WriteToSnoMask('X',"%s added permanent %s%s on %s: %s",setter.c_str(),params[0].c_str(),params[0].length() == 1 ? "-line" : "", params[1].c_str(),params[5].c_str()); } params[5] = ":" + params[5]; diff --git a/src/modules/m_spanningtree/admin.cpp b/src/modules/m_spanningtree/admin.cpp index 133da928b..e47078c7e 100644 --- a/src/modules/m_spanningtree/admin.cpp +++ b/src/modules/m_spanningtree/admin.cpp @@ -25,30 +25,30 @@ bool TreeSocket::Admin(const std::string &prefix, parameterlist ¶ms) { if (params.size() > 0) { - if (InspIRCd::Match(this->ServerInstance->Config->ServerName, params[0])) + if (InspIRCd::Match(ServerInstance->Config->ServerName, params[0])) { /* It's for our server */ string_list results; - User* source = this->ServerInstance->FindNick(prefix); + User* source = ServerInstance->FindNick(prefix); if (source) { parameterlist par; par.push_back(prefix); par.push_back(""); par[1] = std::string("::")+ServerInstance->Config->ServerName+" 256 "+source->nick+" :Administrative info for "+ServerInstance->Config->ServerName; - Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server); + Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH",par, source->server); par[1] = std::string("::")+ServerInstance->Config->ServerName+" 257 "+source->nick+" :Name - "+ServerInstance->Config->AdminName; - Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server); + Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH",par, source->server); par[1] = std::string("::")+ServerInstance->Config->ServerName+" 258 "+source->nick+" :Nickname - "+ServerInstance->Config->AdminNick; - Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server); + Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH",par, source->server); par[1] = std::string("::")+ServerInstance->Config->ServerName+" 258 "+source->nick+" :E-Mail - "+ServerInstance->Config->AdminEmail; - Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server); + Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH",par, source->server); } } else { /* Pass it on */ - User* source = this->ServerInstance->FindNick(prefix); + User* source = ServerInstance->FindNick(prefix); if (source) Utils->DoOneToOne(prefix, "ADMIN", params, params[0]); } diff --git a/src/modules/m_spanningtree/away.cpp b/src/modules/m_spanningtree/away.cpp index 2aac26bbd..354266554 100644 --- a/src/modules/m_spanningtree/away.cpp +++ b/src/modules/m_spanningtree/away.cpp @@ -20,7 +20,7 @@ bool TreeSocket::Away(const std::string &prefix, parameterlist ¶ms) { - User* u = this->ServerInstance->FindNick(prefix); + User* u = ServerInstance->FindNick(prefix); if (!u) return true; if (params.size()) diff --git a/src/modules/m_spanningtree/capab.cpp b/src/modules/m_spanningtree/capab.cpp index 66d448e55..7953468e4 100644 --- a/src/modules/m_spanningtree/capab.cpp +++ b/src/modules/m_spanningtree/capab.cpp @@ -23,7 +23,7 @@ std::string TreeSocket::MyModules(int filter) { - std::vector<std::string> modlist = this->ServerInstance->Modules->GetAllModuleNames(filter); + std::vector<std::string> modlist = ServerInstance->Modules->GetAllModuleNames(filter); if (filter == VF_COMMON && proto_version != ProtocolVersion) CompatAddModules(modlist); @@ -236,13 +236,13 @@ bool TreeSocket::Capab(const parameterlist ¶ms) } } - if(this->CapKeys.find("PREFIX") != this->CapKeys.end() && this->CapKeys.find("PREFIX")->second != this->ServerInstance->Modes->BuildPrefixes()) + if(this->CapKeys.find("PREFIX") != this->CapKeys.end() && this->CapKeys.find("PREFIX")->second != ServerInstance->Modes->BuildPrefixes()) reason = "One or more of the prefixes on the remote server are invalid on this server."; - if(this->CapKeys.find("CHANMODES") != this->CapKeys.end() && this->CapKeys.find("CHANMODES")->second != this->ServerInstance->Modes->GiveModeList(MASK_CHANNEL)) + if(this->CapKeys.find("CHANMODES") != this->CapKeys.end() && this->CapKeys.find("CHANMODES")->second != ServerInstance->Modes->GiveModeList(MASK_CHANNEL)) reason = "One or more of the channel modes on the remote server are invalid on this server."; - if(this->CapKeys.find("USERMODES") != this->CapKeys.end() && this->CapKeys.find("USERMODES")->second != this->ServerInstance->Modes->GiveModeList(MASK_USER)) + if(this->CapKeys.find("USERMODES") != this->CapKeys.end() && this->CapKeys.find("USERMODES")->second != ServerInstance->Modes->GiveModeList(MASK_USER)) reason = "One or more of the user modes on the remote server are invalid on this server."; @@ -255,8 +255,8 @@ bool TreeSocket::Capab(const parameterlist ¶ms) if (!this->GetTheirChallenge().empty() && (this->LinkState == CONNECTING)) { this->SendCapabilities(2); - this->WriteLine(std::string("SERVER ")+this->ServerInstance->Config->ServerName+" "+this->MakePass(OutboundPass, this->GetTheirChallenge())+" 0 "+ - ServerInstance->Config->GetSID()+" :"+this->ServerInstance->Config->ServerDesc); + this->WriteLine(std::string("SERVER ")+ServerInstance->Config->ServerName+" "+this->MakePass(OutboundPass, this->GetTheirChallenge())+" 0 "+ + ServerInstance->Config->GetSID()+" :"+ServerInstance->Config->ServerDesc); } } else @@ -265,7 +265,7 @@ bool TreeSocket::Capab(const parameterlist ¶ms) if (this->LinkState == CONNECTING) { this->SendCapabilities(2); - this->WriteLine(std::string("SERVER ")+this->ServerInstance->Config->ServerName+" "+OutboundPass+" 0 "+ServerInstance->Config->GetSID()+" :"+this->ServerInstance->Config->ServerDesc); + this->WriteLine(std::string("SERVER ")+ServerInstance->Config->ServerName+" "+OutboundPass+" 0 "+ServerInstance->Config->GetSID()+" :"+ServerInstance->Config->ServerDesc); } } diff --git a/src/modules/m_spanningtree/compat.cpp b/src/modules/m_spanningtree/compat.cpp index 8a6e6855f..71272edec 100644 --- a/src/modules/m_spanningtree/compat.cpp +++ b/src/modules/m_spanningtree/compat.cpp @@ -82,7 +82,7 @@ void TreeSocket::WriteLine(std::string line) ServerInstance->Logs->Log("m_spanningtree",DEBUG, "S[%d] O %s", this->GetFd(), line.c_str()); line.append("\r\n"); - this->Write(line); + this->WriteData(line); } diff --git a/src/modules/m_spanningtree/delline.cpp b/src/modules/m_spanningtree/delline.cpp index a1a9089ad..cadcdd14b 100644 --- a/src/modules/m_spanningtree/delline.cpp +++ b/src/modules/m_spanningtree/delline.cpp @@ -42,7 +42,7 @@ bool TreeSocket::DelLine(const std::string &prefix, parameterlist ¶ms) /* NOTE: No check needed on 'user', this function safely handles NULL */ if (ServerInstance->XLines->DelLine(params[1].c_str(), params[0], user)) { - this->ServerInstance->SNO->WriteToSnoMask('X',"%s removed %s%s on %s", setter.c_str(), + ServerInstance->SNO->WriteToSnoMask('X',"%s removed %s%s on %s", setter.c_str(), params[0].c_str(), params[0].length() == 1 ? "-line" : "", params[1].c_str()); Utils->DoOneToAllButSender(prefix,"DELLINE", params, prefix); } diff --git a/src/modules/m_spanningtree/encap.cpp b/src/modules/m_spanningtree/encap.cpp index 7b85a49d0..175257b0a 100644 --- a/src/modules/m_spanningtree/encap.cpp +++ b/src/modules/m_spanningtree/encap.cpp @@ -29,7 +29,7 @@ bool TreeSocket::Encap(const std::string &prefix, parameterlist ¶ms) { if (InspIRCd::Match(ServerInstance->Config->GetSID(), params[0])) { - User* who = this->ServerInstance->FindUUID(prefix); + User* who = ServerInstance->FindUUID(prefix); if (!who) who = Utils->ServerUser; diff --git a/src/modules/m_spanningtree/fhost.cpp b/src/modules/m_spanningtree/fhost.cpp index 1595b98aa..d31cffa39 100644 --- a/src/modules/m_spanningtree/fhost.cpp +++ b/src/modules/m_spanningtree/fhost.cpp @@ -25,7 +25,7 @@ bool TreeSocket::ChangeHost(const std::string &prefix, parameterlist ¶ms) { if (params.size() < 1) return true; - User* u = this->ServerInstance->FindNick(prefix); + User* u = ServerInstance->FindNick(prefix); if (u) { diff --git a/src/modules/m_spanningtree/fident.cpp b/src/modules/m_spanningtree/fident.cpp index 0744d9bf2..8cd3618db 100644 --- a/src/modules/m_spanningtree/fident.cpp +++ b/src/modules/m_spanningtree/fident.cpp @@ -25,7 +25,7 @@ bool TreeSocket::ChangeIdent(const std::string &prefix, parameterlist ¶ms) { if (params.size() < 1) return true; - User* u = this->ServerInstance->FindNick(prefix); + User* u = ServerInstance->FindNick(prefix); if (u) { u->ChangeIdent(params[0].c_str()); diff --git a/src/modules/m_spanningtree/fjoin.cpp b/src/modules/m_spanningtree/fjoin.cpp index 2c3606db1..7f11f40dd 100644 --- a/src/modules/m_spanningtree/fjoin.cpp +++ b/src/modules/m_spanningtree/fjoin.cpp @@ -59,7 +59,7 @@ bool TreeSocket::ForceJoin(const std::string &source, parameterlist ¶ms) time_t TS = atoi(params[1].c_str()); /* Timestamp given to us for remote side */ irc::tokenstream users((params.size() > 3) ? params[params.size() - 1] : ""); /* users from the user list */ bool apply_other_sides_modes = true; /* True if we are accepting the other side's modes */ - Channel* chan = this->ServerInstance->FindChan(channel); /* The channel we're sending joins to */ + Channel* chan = ServerInstance->FindChan(channel); /* The channel we're sending joins to */ bool created = !chan; /* True if the channel doesnt exist here yet */ std::string item; /* One item in the list of nicks */ @@ -123,7 +123,7 @@ bool TreeSocket::ForceJoin(const std::string &source, parameterlist ¶ms) modelist.push_back(params[idx]); } - this->ServerInstance->SendMode(modelist, Utils->ServerUser); + ServerInstance->SendMode(modelist, Utils->ServerUser); } /* Now, process every 'modes,nick' pair */ @@ -156,7 +156,7 @@ bool TreeSocket::ForceJoin(const std::string &source, parameterlist ¶ms) usr++; /* Check the user actually exists */ - who = this->ServerInstance->FindUUID(usr); + who = ServerInstance->FindUUID(usr); if (who) { /* Check that the user's 'direction' is correct */ @@ -168,7 +168,7 @@ bool TreeSocket::ForceJoin(const std::string &source, parameterlist ¶ms) for (std::string::iterator x = modes.begin(); x != modes.end(); ++x) modestack.Push(*x, who->nick); - Channel::JoinUser(this->ServerInstance, who, channel.c_str(), true, "", route_back_again->bursting, TS); + Channel::JoinUser(ServerInstance, who, channel.c_str(), true, "", route_back_again->bursting, TS); } else { diff --git a/src/modules/m_spanningtree/fmode.cpp b/src/modules/m_spanningtree/fmode.cpp index 3421f8045..3bca098d6 100644 --- a/src/modules/m_spanningtree/fmode.cpp +++ b/src/modules/m_spanningtree/fmode.cpp @@ -34,7 +34,7 @@ bool TreeSocket::ForceMode(const std::string &source, parameterlist ¶ms) std::string sourceserv; /* Are we dealing with an FMODE from a user, or from a server? */ - User* who = this->ServerInstance->FindNick(source); + User* who = ServerInstance->FindNick(source); if (who) { /* FMODE from a user, set sourceserv to the users server name */ @@ -66,7 +66,7 @@ bool TreeSocket::ForceMode(const std::string &source, parameterlist ¶ms) } /* Extract the TS value of the object, either User or Channel */ - User* dst = this->ServerInstance->FindNick(params[0]); + User* dst = ServerInstance->FindNick(params[0]); Channel* chan = NULL; time_t ourTS = 0; @@ -76,7 +76,7 @@ bool TreeSocket::ForceMode(const std::string &source, parameterlist ¶ms) } else { - chan = this->ServerInstance->FindChan(params[0]); + chan = ServerInstance->FindChan(params[0]); if (chan) { ourTS = chan->age; diff --git a/src/modules/m_spanningtree/fname.cpp b/src/modules/m_spanningtree/fname.cpp index a83591a4f..cc7625f12 100644 --- a/src/modules/m_spanningtree/fname.cpp +++ b/src/modules/m_spanningtree/fname.cpp @@ -25,7 +25,7 @@ bool TreeSocket::ChangeName(const std::string &prefix, parameterlist ¶ms) { if (params.size() < 1) return true; - User* u = this->ServerInstance->FindNick(prefix); + User* u = ServerInstance->FindNick(prefix); if (u) { u->ChangeName(params[0].c_str()); diff --git a/src/modules/m_spanningtree/ftopic.cpp b/src/modules/m_spanningtree/ftopic.cpp index 34e97dd11..5a6656e3e 100644 --- a/src/modules/m_spanningtree/ftopic.cpp +++ b/src/modules/m_spanningtree/ftopic.cpp @@ -27,14 +27,14 @@ bool TreeSocket::ForceTopic(const std::string &source, parameterlist ¶ms) if (params.size() != 4) return true; time_t ts = atoi(params[1].c_str()); - Channel* c = this->ServerInstance->FindChan(params[0]); + Channel* c = ServerInstance->FindChan(params[0]); if (c) { if ((ts >= c->topicset) || (c->topic.empty())) { if (c->topic != params[3]) { - User* user = this->ServerInstance->FindNick(source); + User* user = ServerInstance->FindNick(source); // Update topic only when it differs from current topic c->topic.assign(params[3], 0, ServerInstance->Config->Limits.MaxTopic); if (!user) diff --git a/src/modules/m_spanningtree/handshaketimer.cpp b/src/modules/m_spanningtree/handshaketimer.cpp index 56f34283b..814aa122c 100644 --- a/src/modules/m_spanningtree/handshaketimer.cpp +++ b/src/modules/m_spanningtree/handshaketimer.cpp @@ -37,15 +37,15 @@ HandshakeTimer::~HandshakeTimer() void HandshakeTimer::Tick(time_t TIME) { - if (!sock->GetHook()) + if (!sock->GetIOHook()) { CancelRepeat(); sock->SendCapabilities(1); } - else if (BufferedSocketHSCompleteRequest(sock, (Module*)Utils->Creator, sock->GetHook()).Send()) + else if (BufferedSocketHSCompleteRequest(sock, Utils->Creator, sock->GetIOHook()).Send()) { CancelRepeat(); - BufferedSocketAttachCertRequest(sock, (Module*)Utils->Creator, sock->GetHook()).Send(); + BufferedSocketAttachCertRequest(sock, Utils->Creator, sock->GetIOHook()).Send(); sock->SendCapabilities(1); } // otherwise, try again later diff --git a/src/modules/m_spanningtree/hmac.cpp b/src/modules/m_spanningtree/hmac.cpp index cc1b33f23..b7cddc47a 100644 --- a/src/modules/m_spanningtree/hmac.cpp +++ b/src/modules/m_spanningtree/hmac.cpp @@ -129,9 +129,9 @@ bool TreeSocket::ComparePass(const Link& link, const std::string &theirs) this->auth_challenge = !ourchallenge.empty() && !theirchallenge.empty(); std::string fp; - if (GetHook()) + if (GetIOHook()) { - BufferedSocketCertificateRequest req(this, Utils->Creator, GetHook()); + BufferedSocketCertificateRequest req(this, Utils->Creator, GetIOHook()); req.Send(); if (req.cert) { diff --git a/src/modules/m_spanningtree/kill.cpp b/src/modules/m_spanningtree/kill.cpp index c2026d0bb..e76fc7f3e 100644 --- a/src/modules/m_spanningtree/kill.cpp +++ b/src/modules/m_spanningtree/kill.cpp @@ -28,7 +28,7 @@ bool TreeSocket::RemoteKill(const std::string &prefix, parameterlist ¶ms) if (params.size() != 2) return true; - User* who = this->ServerInstance->FindNick(params[0]); + User* who = ServerInstance->FindNick(params[0]); if (who) { @@ -46,7 +46,7 @@ bool TreeSocket::RemoteKill(const std::string &prefix, parameterlist ¶ms) // this shouldn't ever be null, but it doesn't hurt to check who->Write(":%s KILL %s :%s (%s)", src->GetName().c_str(), who->nick.c_str(), src->GetName().c_str(), reason.c_str()); } - this->ServerInstance->Users->QuitUser(who, reason); + ServerInstance->Users->QuitUser(who, reason); } return true; } diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp index 1bc3dfe39..230c3109b 100644 --- a/src/modules/m_spanningtree/main.cpp +++ b/src/modules/m_spanningtree/main.cpp @@ -275,7 +275,7 @@ void ModuleSpanningTree::ConnectServer(Link* x, Autoconnect* y) /* Gave a hook, but it wasnt one we know */ if ((!x->Hook.empty()) && (Utils->hooks.find(x->Hook.c_str()) == Utils->hooks.end())) return; - TreeSocket* newsocket = new TreeSocket(Utils, ServerInstance, x->IPAddr,x->Port, x->Timeout ? x->Timeout : 10,x->Name.c_str(), x->Bind, y, x->Hook.empty() ? NULL : Utils->hooks[x->Hook.c_str()]); + TreeSocket* newsocket = new TreeSocket(Utils, x->IPAddr,x->Port, x->Timeout ? x->Timeout : 10,x->Name.c_str(), x->Bind, y, x->Hook.empty() ? NULL : Utils->hooks[x->Hook.c_str()]); if (newsocket->GetFd() > -1) { /* Handled automatically on success */ @@ -283,8 +283,7 @@ void ModuleSpanningTree::ConnectServer(Link* x, Autoconnect* y) else { ServerInstance->SNO->WriteToSnoMask('l', "CONNECT: Error connecting \002%s\002: %s.",x->Name.c_str(),strerror(errno)); - if (ServerInstance->SocketCull.find(newsocket) == ServerInstance->SocketCull.end()) - ServerInstance->SocketCull[newsocket] = newsocket; + ServerInstance->GlobalCulls.AddItem(newsocket); Utils->DoFailOver(y); } } diff --git a/src/modules/m_spanningtree/metadata.cpp b/src/modules/m_spanningtree/metadata.cpp index 40a98d93b..135970a4a 100644 --- a/src/modules/m_spanningtree/metadata.cpp +++ b/src/modules/m_spanningtree/metadata.cpp @@ -33,26 +33,26 @@ bool TreeSocket::MetaData(const std::string &prefix, parameterlist ¶ms) { if (params[0] == "*") { - FOREACH_MOD_I(this->ServerInstance,I_OnDecodeMetaData,OnDecodeMetaData(NULL,params[1],params[2])); + FOREACH_MOD_I(ServerInstance,I_OnDecodeMetaData,OnDecodeMetaData(NULL,params[1],params[2])); } else if (*(params[0].c_str()) == '#') { - Channel* c = this->ServerInstance->FindChan(params[0]); + Channel* c = ServerInstance->FindChan(params[0]); if (c) { if (item) item->unserialize(FORMAT_NETWORK, c, params[2]); - FOREACH_MOD_I(this->ServerInstance,I_OnDecodeMetaData,OnDecodeMetaData(c,params[1],params[2])); + FOREACH_MOD_I(ServerInstance,I_OnDecodeMetaData,OnDecodeMetaData(c,params[1],params[2])); } } else if (*(params[0].c_str()) != '#') { - User* u = this->ServerInstance->FindNick(params[0]); + User* u = ServerInstance->FindNick(params[0]); if (u) { if (item) item->unserialize(FORMAT_NETWORK, u, params[2]); - FOREACH_MOD_I(this->ServerInstance,I_OnDecodeMetaData,OnDecodeMetaData(u,params[1],params[2])); + FOREACH_MOD_I(ServerInstance,I_OnDecodeMetaData,OnDecodeMetaData(u,params[1],params[2])); } } } diff --git a/src/modules/m_spanningtree/modules.cpp b/src/modules/m_spanningtree/modules.cpp index 6c9132794..7a20a98ff 100644 --- a/src/modules/m_spanningtree/modules.cpp +++ b/src/modules/m_spanningtree/modules.cpp @@ -26,7 +26,7 @@ bool TreeSocket::Modules(const std::string &prefix, parameterlist ¶ms) if (params.empty()) return true; - if (!InspIRCd::Match(this->ServerInstance->Config->ServerName, params[0])) + if (!InspIRCd::Match(ServerInstance->Config->ServerName, params[0])) { /* Pass it on, not for us */ Utils->DoOneToOne(prefix, "MODULES", params, params[0]); @@ -38,7 +38,7 @@ bool TreeSocket::Modules(const std::string &prefix, parameterlist ¶ms) par.push_back(prefix); par.push_back(""); - User* source = this->ServerInstance->FindNick(prefix); + User* source = ServerInstance->FindNick(prefix); if (!source) return true; diff --git a/src/modules/m_spanningtree/motd.cpp b/src/modules/m_spanningtree/motd.cpp index e42c53152..0c775d644 100644 --- a/src/modules/m_spanningtree/motd.cpp +++ b/src/modules/m_spanningtree/motd.cpp @@ -27,11 +27,11 @@ bool TreeSocket::Motd(const std::string &prefix, parameterlist ¶ms) { if (params.size() > 0) { - if (InspIRCd::Match(this->ServerInstance->Config->ServerName, params[0])) + if (InspIRCd::Match(ServerInstance->Config->ServerName, params[0])) { /* It's for our server */ string_list results; - User* source = this->ServerInstance->FindNick(prefix); + User* source = ServerInstance->FindNick(prefix); if (source) { @@ -42,27 +42,27 @@ bool TreeSocket::Motd(const std::string &prefix, parameterlist ¶ms) if (!ServerInstance->Config->MOTD.size()) { par[1] = std::string("::")+ServerInstance->Config->ServerName+" 422 "+source->nick+" :Message of the day file is missing."; - Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server); + Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH",par, source->server); return true; } par[1] = std::string("::")+ServerInstance->Config->ServerName+" 375 "+source->nick+" :"+ServerInstance->Config->ServerName+" message of the day"; - Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server); + Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH",par, source->server); for (unsigned int i = 0; i < ServerInstance->Config->MOTD.size(); i++) { par[1] = std::string("::")+ServerInstance->Config->ServerName+" 372 "+source->nick+" :- "+ServerInstance->Config->MOTD[i]; - Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server); + Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH",par, source->server); } par[1] = std::string("::")+ServerInstance->Config->ServerName+" 376 "+source->nick+" :End of message of the day."; - Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server); + Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH",par, source->server); } } else { /* Pass it on */ - User* source = this->ServerInstance->FindNick(prefix); + User* source = ServerInstance->FindNick(prefix); if (source) Utils->DoOneToOne(prefix, "MOTD", params, params[0]); } diff --git a/src/modules/m_spanningtree/netburst.cpp b/src/modules/m_spanningtree/netburst.cpp index ada10e6a1..3cfad9b63 100644 --- a/src/modules/m_spanningtree/netburst.cpp +++ b/src/modules/m_spanningtree/netburst.cpp @@ -30,16 +30,16 @@ void TreeSocket::DoBurst(TreeServer* s) { std::string name = s->GetName(); - std::string burst = ":" + this->ServerInstance->Config->GetSID() + " BURST " +ConvToStr(ServerInstance->Time()); - std::string endburst = ":" + this->ServerInstance->Config->GetSID() + " ENDBURST"; - this->ServerInstance->SNO->WriteToSnoMask('l',"Bursting to \2%s\2 (Authentication: %s%s).", + std::string burst = ":" + ServerInstance->Config->GetSID() + " BURST " +ConvToStr(ServerInstance->Time()); + std::string endburst = ":" + ServerInstance->Config->GetSID() + " ENDBURST"; + ServerInstance->SNO->WriteToSnoMask('l',"Bursting to \2%s\2 (Authentication: %s%s).", name.c_str(), this->auth_fingerprint ? "SSL Fingerprint and " : "", this->auth_challenge ? "challenge-response" : "plaintext password"); this->CleanNegotiationInfo(); this->WriteLine(burst); /* send our version string */ - this->WriteLine(std::string(":")+this->ServerInstance->Config->GetSID()+" VERSION :"+this->ServerInstance->GetVersionString()); + this->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" VERSION :"+ServerInstance->GetVersionString()); /* Send server tree */ this->SendServers(Utils->TreeRoot,s,1); /* Send users and their oper status */ @@ -47,9 +47,9 @@ void TreeSocket::DoBurst(TreeServer* s) /* Send everything else (channel modes, xlines etc) */ this->SendChannelModes(s); this->SendXLines(s); - FOREACH_MOD_I(this->ServerInstance,I_OnSyncNetwork,OnSyncNetwork(Utils->Creator,(void*)this)); + FOREACH_MOD_I(ServerInstance,I_OnSyncNetwork,OnSyncNetwork(Utils->Creator,(void*)this)); this->WriteLine(endburst); - this->ServerInstance->SNO->WriteToSnoMask('l',"Finished bursting to \2"+name+"\2."); + ServerInstance->SNO->WriteToSnoMask('l',"Finished bursting to \2"+name+"\2."); } /** Recursively send the server tree with distances as hops. @@ -91,7 +91,7 @@ void TreeSocket::SendFJoins(TreeServer* Current, Channel* c) size_t curlen, headlen; curlen = headlen = snprintf(list,MAXBUF,":%s FJOIN %s %lu +%s :", - this->ServerInstance->Config->GetSID().c_str(), c->name.c_str(), (unsigned long)c->age, c->ChanModes(true)); + ServerInstance->Config->GetSID().c_str(), c->name.c_str(), (unsigned long)c->age, c->ChanModes(true)); int numusers = 0; char* ptr = list + curlen; bool looped_once = false; @@ -103,7 +103,7 @@ void TreeSocket::SendFJoins(TreeServer* Current, Channel* c) for (UserMembCIter i = ulist->begin(); i != ulist->end(); i++) { size_t ptrlen = 0; - std::string modestr = this->ServerInstance->Modes->ModeString(i->first, c, false); + std::string modestr = ServerInstance->Modes->ModeString(i->first, c, false); if ((curlen + modestr.length() + i->first->uuid.length() + 4) > 480) { @@ -150,7 +150,7 @@ void TreeSocket::SendFJoins(TreeServer* Current, Channel* c) if ((params.length() >= ServerInstance->Config->Limits.MaxModes) || (currsize > 350)) { /* Wrap at MAXMODES */ - buffer.append(":").append(this->ServerInstance->Config->GetSID()).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(modes).append(params).append("\r\n"); + buffer.append(":").append(ServerInstance->Config->GetSID()).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(modes).append(params).append("\r\n"); modes.clear(); params.clear(); linesize = 1; @@ -159,7 +159,7 @@ void TreeSocket::SendFJoins(TreeServer* Current, Channel* c) /* Only send these if there are any */ if (!modes.empty()) - buffer.append(":").append(this->ServerInstance->Config->GetSID()).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(modes).append(params); + buffer.append(":").append(ServerInstance->Config->GetSID()).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(modes).append(params); this->WriteLine(buffer); } @@ -168,7 +168,7 @@ void TreeSocket::SendFJoins(TreeServer* Current, Channel* c) void TreeSocket::SendXLines(TreeServer* Current) { char data[MAXBUF]; - std::string n = this->ServerInstance->Config->GetSID(); + std::string n = ServerInstance->Config->GetSID(); const char* sn = n.c_str(); std::vector<std::string> types = ServerInstance->XLines->GetAllTypes(); @@ -209,9 +209,9 @@ void TreeSocket::SendChannelModes(TreeServer* Current) { char data[MAXBUF]; std::deque<std::string> list; - std::string n = this->ServerInstance->Config->GetSID(); + std::string n = ServerInstance->Config->GetSID(); const char* sn = n.c_str(); - for (chan_hash::iterator c = this->ServerInstance->chanlist->begin(); c != this->ServerInstance->chanlist->end(); c++) + for (chan_hash::iterator c = ServerInstance->chanlist->begin(); c != ServerInstance->chanlist->end(); c++) { SendFJoins(Current, c->second); if (!c->second->topic.empty()) @@ -230,7 +230,7 @@ void TreeSocket::SendChannelModes(TreeServer* Current) Utils->Creator->ProtoSendMetaData(this, c->second, i->first, value); } - FOREACH_MOD_I(this->ServerInstance,I_OnSyncChannel,OnSyncChannel(c->second,Utils->Creator,this)); + FOREACH_MOD_I(ServerInstance,I_OnSyncChannel,OnSyncChannel(c->second,Utils->Creator,this)); } } @@ -239,7 +239,7 @@ void TreeSocket::SendUsers(TreeServer* Current) { char data[MAXBUF]; std::string dataline; - for (user_hash::iterator u = this->ServerInstance->Users->clientlist->begin(); u != this->ServerInstance->Users->clientlist->end(); u++) + for (user_hash::iterator u = ServerInstance->Users->clientlist->begin(); u != ServerInstance->Users->clientlist->end(); u++) { if (u->second->registered == REG_ALL) { @@ -281,7 +281,7 @@ void TreeSocket::SendUsers(TreeServer* Current) Utils->Creator->ProtoSendMetaData(this, u->second, i->first, value); } - FOREACH_MOD_I(this->ServerInstance,I_OnSyncUser,OnSyncUser(u->second,Utils->Creator,this)); + FOREACH_MOD_I(ServerInstance,I_OnSyncUser,OnSyncUser(u->second,Utils->Creator,this)); } } } diff --git a/src/modules/m_spanningtree/nickcollide.cpp b/src/modules/m_spanningtree/nickcollide.cpp index a723c114f..4481ba35e 100644 --- a/src/modules/m_spanningtree/nickcollide.cpp +++ b/src/modules/m_spanningtree/nickcollide.cpp @@ -114,7 +114,7 @@ int TreeSocket::DoCollision(User *u, time_t remotets, const std::string &remotei } if (bChangeRemote) { - User *remote = this->ServerInstance->FindUUID(remoteuid); + User *remote = ServerInstance->FindUUID(remoteuid); /* * remote side needs to change. If this happens, we will modify * the UID or halt the propagation of the nick change command, diff --git a/src/modules/m_spanningtree/operquit.cpp b/src/modules/m_spanningtree/operquit.cpp index 5cdee3bc6..9128baa0f 100644 --- a/src/modules/m_spanningtree/operquit.cpp +++ b/src/modules/m_spanningtree/operquit.cpp @@ -26,7 +26,7 @@ bool TreeSocket::OperQuit(const std::string &prefix, parameterlist ¶ms) if (params.size() < 1) return true; - User* u = this->ServerInstance->FindNick(prefix); + User* u = ServerInstance->FindNick(prefix); if (u) { diff --git a/src/modules/m_spanningtree/opertype.cpp b/src/modules/m_spanningtree/opertype.cpp index c1105aa71..a1ad88007 100644 --- a/src/modules/m_spanningtree/opertype.cpp +++ b/src/modules/m_spanningtree/opertype.cpp @@ -29,11 +29,11 @@ bool TreeSocket::OperType(const std::string &prefix, parameterlist ¶ms) if (params.size() != 1) return true; std::string opertype = params[0]; - User* u = this->ServerInstance->FindNick(prefix); + User* u = ServerInstance->FindNick(prefix); if (u) { if (!IS_OPER(u)) - this->ServerInstance->Users->all_opers.push_back(u); + ServerInstance->Users->all_opers.push_back(u); u->modes[UM_OPERATOR] = 1; u->oper.assign(opertype, 0, 512); Utils->DoOneToAllButSender(u->uuid, "OPERTYPE", params, u->server); @@ -49,7 +49,7 @@ bool TreeSocket::OperType(const std::string &prefix, parameterlist ¶ms) */ if ( remoteserver->bursting || - this->ServerInstance->SilentULine(this->ServerInstance->FindServerNamePtr(u->server)) + ServerInstance->SilentULine(ServerInstance->FindServerNamePtr(u->server)) ) { dosend = false; @@ -57,7 +57,7 @@ bool TreeSocket::OperType(const std::string &prefix, parameterlist ¶ms) } if (dosend) - this->ServerInstance->SNO->WriteToSnoMask('O',"From %s: User %s (%s@%s) is now an IRC operator of type %s",u->server, u->nick.c_str(),u->ident.c_str(), u->host.c_str(), irc::Spacify(opertype.c_str())); + ServerInstance->SNO->WriteToSnoMask('O',"From %s: User %s (%s@%s) is now an IRC operator of type %s",u->server, u->nick.c_str(),u->ident.c_str(), u->host.c_str(), irc::Spacify(opertype.c_str())); } return true; } diff --git a/src/modules/m_spanningtree/override_stats.cpp b/src/modules/m_spanningtree/override_stats.cpp index 9986763d9..5d0239f84 100644 --- a/src/modules/m_spanningtree/override_stats.cpp +++ b/src/modules/m_spanningtree/override_stats.cpp @@ -78,8 +78,8 @@ ModResult ModuleSpanningTree::OnStats(char statschar, User* user, string_list &r ip = "*"; std::string transport("plaintext"); - if (Utils->Bindings[i]->GetIOHook()) - transport = BufferedSocketNameRequest(this, Utils->Bindings[i]->GetIOHook()).Send(); + if (Utils->Bindings[i]->Hook) + transport = BufferedSocketNameRequest(this, Utils->Bindings[i]->Hook).Send(); results.push_back(ConvToStr(ServerInstance->Config->ServerName) + " 249 "+user->nick+" :" + ip + ":" + ConvToStr(Utils->Bindings[i]->GetPort())+ " (server, " + transport + ")"); diff --git a/src/modules/m_spanningtree/ping.cpp b/src/modules/m_spanningtree/ping.cpp index 1318b60a0..c3467c984 100644 --- a/src/modules/m_spanningtree/ping.cpp +++ b/src/modules/m_spanningtree/ping.cpp @@ -31,13 +31,13 @@ bool TreeSocket::LocalPing(const std::string &prefix, parameterlist ¶ms) if (params.size() == 1) { std::string stufftobounce = params[0]; - this->WriteLine(std::string(":")+this->ServerInstance->Config->GetSID()+" PONG "+stufftobounce); + this->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" PONG "+stufftobounce); return true; } else { std::string forwardto = params[1]; - if (forwardto == this->ServerInstance->Config->ServerName || forwardto == this->ServerInstance->Config->GetSID()) + if (forwardto == ServerInstance->Config->ServerName || forwardto == ServerInstance->Config->GetSID()) { // this is a ping for us, send back PONG to the requesting server params[1] = params[0]; diff --git a/src/modules/m_spanningtree/pong.cpp b/src/modules/m_spanningtree/pong.cpp index b551ef6d2..274641897 100644 --- a/src/modules/m_spanningtree/pong.cpp +++ b/src/modules/m_spanningtree/pong.cpp @@ -52,7 +52,7 @@ bool TreeSocket::LocalPong(const std::string &prefix, parameterlist ¶ms) * dump the PONG reply back to their fd. If its a server, do nowt. * Services might want to send these s->s, but we dont need to yet. */ - User* u = this->ServerInstance->FindNick(prefix); + User* u = ServerInstance->FindNick(prefix); if (u) { u->WriteServ("PONG %s %s",params[0].c_str(),params[1].c_str()); diff --git a/src/modules/m_spanningtree/push.cpp b/src/modules/m_spanningtree/push.cpp index 88c6b55bd..778c2291c 100644 --- a/src/modules/m_spanningtree/push.cpp +++ b/src/modules/m_spanningtree/push.cpp @@ -28,7 +28,7 @@ bool TreeSocket::Push(const std::string &prefix, parameterlist ¶ms) { if (params.size() < 2) return true; - User* u = this->ServerInstance->FindNick(params[0]); + User* u = ServerInstance->FindNick(params[0]); if (!u) return true; if (IS_LOCAL(u)) diff --git a/src/modules/m_spanningtree/resolvers.cpp b/src/modules/m_spanningtree/resolvers.cpp index 73e67c4f7..c7c49b348 100644 --- a/src/modules/m_spanningtree/resolvers.cpp +++ b/src/modules/m_spanningtree/resolvers.cpp @@ -49,7 +49,7 @@ void ServernameResolver::OnLookupComplete(const std::string &result, unsigned in if ((!MyLink.Hook.empty()) && (Utils->hooks.find(MyLink.Hook.c_str()) == Utils->hooks.end())) return; - TreeSocket* newsocket = new TreeSocket(this->Utils, ServerInstance, result,MyLink.Port,MyLink.Timeout ? MyLink.Timeout : 10,MyLink.Name.c_str(), + TreeSocket* newsocket = new TreeSocket(this->Utils, result,MyLink.Port,MyLink.Timeout ? MyLink.Timeout : 10,MyLink.Name.c_str(), MyLink.Bind, myautoconnect, MyLink.Hook.empty() ? NULL : Utils->hooks[MyLink.Hook.c_str()]); if (newsocket->GetFd() > -1) { @@ -59,8 +59,7 @@ void ServernameResolver::OnLookupComplete(const std::string &result, unsigned in { /* Something barfed, show the opers */ ServerInstance->SNO->WriteToSnoMask('l', "CONNECT: Error connecting \002%s\002: %s.",MyLink.Name.c_str(),strerror(errno)); - if (ServerInstance->SocketCull.find(newsocket) == ServerInstance->SocketCull.end()) - ServerInstance->SocketCull[newsocket] = newsocket; + ServerInstance->GlobalCulls.AddItem(newsocket); Utils->DoFailOver(myautoconnect); } } diff --git a/src/modules/m_spanningtree/save.cpp b/src/modules/m_spanningtree/save.cpp index 9969fdca7..cfa8dc794 100644 --- a/src/modules/m_spanningtree/save.cpp +++ b/src/modules/m_spanningtree/save.cpp @@ -32,7 +32,7 @@ bool TreeSocket::ForceNick(const std::string &prefix, parameterlist ¶ms) if (params.size() < 2) return true; - User* u = this->ServerInstance->FindNick(params[0]); + User* u = ServerInstance->FindNick(params[0]); time_t ts = atol(params[1].c_str()); if (u && u->age == ts) @@ -41,7 +41,7 @@ bool TreeSocket::ForceNick(const std::string &prefix, parameterlist ¶ms) if (!u->ForceNickChange(u->uuid.c_str())) { - this->ServerInstance->Users->QuitUser(u, "Nickname collision"); + ServerInstance->Users->QuitUser(u, "Nickname collision"); } } diff --git a/src/modules/m_spanningtree/server.cpp b/src/modules/m_spanningtree/server.cpp index c275f3490..025675642 100644 --- a/src/modules/m_spanningtree/server.cpp +++ b/src/modules/m_spanningtree/server.cpp @@ -49,7 +49,7 @@ bool TreeSocket::RemoteServer(const std::string &prefix, parameterlist ¶ms) this->SendError("Protocol error - Introduced remote server from unknown server "+ParentOfThis->GetName()); return false; } - if (!this->ServerInstance->IsSID(sid)) + if (!ServerInstance->IsSID(sid)) { this->SendError("Invalid format server ID: "+sid+"!"); return false; @@ -58,26 +58,26 @@ bool TreeSocket::RemoteServer(const std::string &prefix, parameterlist ¶ms) if (CheckDupe) { this->SendError("Server "+servername+" already exists!"); - this->ServerInstance->SNO->WriteToSnoMask('L', "Server \2"+CheckDupe->GetName()+"\2 being introduced from \2" + ParentOfThis->GetName() + "\2 denied, already exists. Closing link with " + ParentOfThis->GetName()); + ServerInstance->SNO->WriteToSnoMask('L', "Server \2"+CheckDupe->GetName()+"\2 being introduced from \2" + ParentOfThis->GetName() + "\2 denied, already exists. Closing link with " + ParentOfThis->GetName()); return false; } CheckDupe = Utils->FindServer(sid); if (CheckDupe) { this->SendError("Server ID "+sid+" already exists! You may want to specify the server ID for the server manually with <server:id> so they do not conflict."); - this->ServerInstance->SNO->WriteToSnoMask('L', "Server \2"+servername+"\2 being introduced from \2" + ParentOfThis->GetName() + "\2 denied, server ID already exists on the network. Closing link with " + ParentOfThis->GetName()); + ServerInstance->SNO->WriteToSnoMask('L', "Server \2"+servername+"\2 being introduced from \2" + ParentOfThis->GetName() + "\2 denied, server ID already exists on the network. Closing link with " + ParentOfThis->GetName()); return false; } Link* lnk = Utils->FindLink(servername); - TreeServer *Node = new TreeServer(this->Utils, this->ServerInstance, servername, description, sid, ParentOfThis,NULL, lnk ? lnk->Hidden : false); + TreeServer *Node = new TreeServer(this->Utils, ServerInstance, servername, description, sid, ParentOfThis,NULL, lnk ? lnk->Hidden : false); ParentOfThis->AddChild(Node); params[4] = ":" + params[4]; Utils->DoOneToAllButSender(prefix,"SERVER",params,prefix); - this->ServerInstance->SNO->WriteToSnoMask('L', "Server \002"+ParentOfThis->GetName()+"\002 introduced server \002"+servername+"\002 ("+description+")"); + ServerInstance->SNO->WriteToSnoMask('L', "Server \002"+ParentOfThis->GetName()+"\002 introduced server \002"+servername+"\002 ("+description+")"); return true; } @@ -110,11 +110,11 @@ bool TreeSocket::Outbound_Reply_Server(parameterlist ¶ms) if (hops) { this->SendError("Server too far away for authentication"); - this->ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, server is too far away for authentication"); + ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, server is too far away for authentication"); return false; } - if (!this->ServerInstance->IsSID(sid)) + if (!ServerInstance->IsSID(sid)) { this->SendError("Invalid format server ID: "+sid+"!"); return false; @@ -127,7 +127,7 @@ bool TreeSocket::Outbound_Reply_Server(parameterlist ¶ms) if (!ComparePass(*x, password)) { - this->ServerInstance->SNO->WriteToSnoMask('l',"Invalid password on link: %s", x->Name.c_str()); + ServerInstance->SNO->WriteToSnoMask('l',"Invalid password on link: %s", x->Name.c_str()); continue; } @@ -135,14 +135,14 @@ bool TreeSocket::Outbound_Reply_Server(parameterlist ¶ms) if (CheckDupe) { this->SendError("Server "+sname+" already exists on server "+CheckDupe->GetParent()->GetName()+"!"); - this->ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, already exists on server "+CheckDupe->GetParent()->GetName()); + ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, already exists on server "+CheckDupe->GetParent()->GetName()); return false; } CheckDupe = Utils->FindServer(sid); if (CheckDupe) { this->SendError("Server ID "+sid+" already exists on the network! You may want to specify the server ID for the server manually with <server:id> so they do not conflict."); - this->ServerInstance->SNO->WriteToSnoMask('l',"Server \2"+assign(servername)+"\2 being introduced denied, server ID already exists on the network. Closing link."); + ServerInstance->SNO->WriteToSnoMask('l',"Server \2"+assign(servername)+"\2 being introduced denied, server ID already exists on the network. Closing link."); return false; } @@ -158,7 +158,7 @@ bool TreeSocket::Outbound_Reply_Server(parameterlist ¶ms) Utils->timeoutlist.erase(this); - TreeServer *Node = new TreeServer(this->Utils, this->ServerInstance, sname, description, sid, Utils->TreeRoot, this, x->Hidden); + TreeServer *Node = new TreeServer(this->Utils, ServerInstance, sname, description, sid, Utils->TreeRoot, this, x->Hidden); Utils->TreeRoot->AddChild(Node); params[4] = ":" + params[4]; @@ -173,7 +173,7 @@ bool TreeSocket::Outbound_Reply_Server(parameterlist ¶ms) } this->SendError("Invalid credentials (check the other server's linking snomask for more information)"); - this->ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, invalid link credentials"); + ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, invalid link credentials"); return false; } @@ -205,11 +205,11 @@ bool TreeSocket::Inbound_Server(parameterlist ¶ms) if (hops) { this->SendError("Server too far away for authentication"); - this->ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, server is too far away for authentication"); + ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, server is too far away for authentication"); return false; } - if (!this->ServerInstance->IsSID(sid)) + if (!ServerInstance->IsSID(sid)) { this->SendError("Invalid format server ID: "+sid+"!"); return false; @@ -222,7 +222,7 @@ bool TreeSocket::Inbound_Server(parameterlist ¶ms) if (!ComparePass(*x, password)) { - this->ServerInstance->SNO->WriteToSnoMask('l',"Invalid password on link: %s", x->Name.c_str()); + ServerInstance->SNO->WriteToSnoMask('l',"Invalid password on link: %s", x->Name.c_str()); continue; } @@ -231,7 +231,7 @@ bool TreeSocket::Inbound_Server(parameterlist ¶ms) if (CheckDupe) { this->SendError("Server "+sname+" already exists on server "+CheckDupe->GetParent()->GetName()+"!"); - this->ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, already exists on server "+CheckDupe->GetParent()->GetName()); + ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, already exists on server "+CheckDupe->GetParent()->GetName()); return false; } @@ -242,30 +242,30 @@ bool TreeSocket::Inbound_Server(parameterlist ¶ms) if (CheckDupe) { this->SendError("Server ID "+CheckDupe->GetID()+" already exists on server "+CheckDupe->GetName()+"! You may want to specify the server ID for the server manually with <server:id> so they do not conflict."); - this->ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, server ID '"+CheckDupe->GetID()+ + ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, server ID '"+CheckDupe->GetID()+ "' already exists on server "+CheckDupe->GetName()); return false; } - this->ServerInstance->SNO->WriteToSnoMask('l',"Verified incoming server connection from \002"+sname+"\002["+(x->HiddenFromStats ? "<hidden>" : this->GetIP())+"] ("+description+")"); - if (this->Hook) + ServerInstance->SNO->WriteToSnoMask('l',"Verified incoming server connection from \002"+sname+"\002["+(x->HiddenFromStats ? "<hidden>" : this->IP)+"] ("+description+")"); + if (this->GetIOHook()) { - std::string name = BufferedSocketNameRequest((Module*)Utils->Creator, this->Hook).Send(); - this->ServerInstance->SNO->WriteToSnoMask('l',"Connection from \2"+sname+"\2["+(x->HiddenFromStats ? "<hidden>" : this->GetIP())+"] using transport \2"+name+"\2"); + std::string name = BufferedSocketNameRequest(Utils->Creator, this->GetIOHook()).Send(); + ServerInstance->SNO->WriteToSnoMask('l',"Connection from \2"+sname+"\2["+(x->HiddenFromStats ? "<hidden>" : this->IP)+"] using transport \2"+name+"\2"); } // this is good. Send our details: Our server name and description and hopcount of 0, // along with the sendpass from this block. this->SendCapabilities(2); - this->WriteLine(std::string("SERVER ")+this->ServerInstance->Config->ServerName+" "+this->MakePass(x->SendPass, this->GetTheirChallenge())+" 0 "+ServerInstance->Config->GetSID()+" :"+this->ServerInstance->Config->ServerDesc); + this->WriteLine(std::string("SERVER ")+ServerInstance->Config->ServerName+" "+this->MakePass(x->SendPass, this->GetTheirChallenge())+" 0 "+ServerInstance->Config->GetSID()+" :"+ServerInstance->Config->ServerDesc); // move to the next state, we are now waiting for THEM. this->LinkState = WAIT_AUTH_2; return true; } this->SendError("Invalid credentials"); - this->ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, invalid link credentials"); + ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, invalid link credentials"); return false; } diff --git a/src/modules/m_spanningtree/stats.cpp b/src/modules/m_spanningtree/stats.cpp index d67c5a3af..71f12d50b 100644 --- a/src/modules/m_spanningtree/stats.cpp +++ b/src/modules/m_spanningtree/stats.cpp @@ -32,11 +32,11 @@ bool TreeSocket::Stats(const std::string &prefix, parameterlist ¶ms) */ if (params.size() > 1) { - if (InspIRCd::Match(this->ServerInstance->Config->ServerName, params[1])) + if (InspIRCd::Match(ServerInstance->Config->ServerName, params[1])) { /* It's for our server */ string_list results; - User* source = this->ServerInstance->FindNick(prefix); + User* source = ServerInstance->FindNick(prefix); if (source) { parameterlist par; @@ -46,14 +46,14 @@ bool TreeSocket::Stats(const std::string &prefix, parameterlist ¶ms) for (size_t i = 0; i < results.size(); i++) { par[1] = "::" + results[i]; - Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server); + Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH",par, source->server); } } } else { /* Pass it on */ - User* source = this->ServerInstance->FindNick(prefix); + User* source = ServerInstance->FindNick(prefix); if (source) Utils->DoOneToOne(source->uuid, "STATS", params, params[1]); } diff --git a/src/modules/m_spanningtree/svsjoin.cpp b/src/modules/m_spanningtree/svsjoin.cpp index b6246e2f4..1664190f8 100644 --- a/src/modules/m_spanningtree/svsjoin.cpp +++ b/src/modules/m_spanningtree/svsjoin.cpp @@ -29,13 +29,13 @@ bool TreeSocket::ServiceJoin(const std::string &prefix, parameterlist ¶ms) if (params.size() < 2) return true; - User* u = this->ServerInstance->FindNick(params[0]); + User* u = ServerInstance->FindNick(params[0]); if (u) { /* only join if it's local, otherwise just pass it on! */ if (IS_LOCAL(u)) - Channel::JoinUser(this->ServerInstance, u, params[1].c_str(), false, "", false, ServerInstance->Time()); + Channel::JoinUser(ServerInstance, u, params[1].c_str(), false, "", false, ServerInstance->Time()); Utils->DoOneToAllButSender(prefix,"SVSJOIN",params,prefix); } return true; diff --git a/src/modules/m_spanningtree/svsnick.cpp b/src/modules/m_spanningtree/svsnick.cpp index 3af6961d0..7a723a36d 100644 --- a/src/modules/m_spanningtree/svsnick.cpp +++ b/src/modules/m_spanningtree/svsnick.cpp @@ -32,7 +32,7 @@ bool TreeSocket::SVSNick(const std::string &prefix, parameterlist ¶ms) if (params.size() < 3) return true; - User* u = this->ServerInstance->FindNick(params[0]); + User* u = ServerInstance->FindNick(params[0]); if (u) { @@ -48,7 +48,7 @@ bool TreeSocket::SVSNick(const std::string &prefix, parameterlist ¶ms) /* buh. UID them */ if (!u->ForceNickChange(u->uuid.c_str())) { - this->ServerInstance->Users->QuitUser(u, "Nickname collision"); + ServerInstance->Users->QuitUser(u, "Nickname collision"); return true; } } diff --git a/src/modules/m_spanningtree/svspart.cpp b/src/modules/m_spanningtree/svspart.cpp index 83e329b4e..1e26c90d9 100644 --- a/src/modules/m_spanningtree/svspart.cpp +++ b/src/modules/m_spanningtree/svspart.cpp @@ -34,8 +34,8 @@ bool TreeSocket::ServicePart(const std::string &prefix, parameterlist ¶ms) if (params.size() == 3) reason = params[2]; - User* u = this->ServerInstance->FindNick(params[0]); - Channel* c = this->ServerInstance->FindChan(params[1]); + User* u = ServerInstance->FindNick(params[0]); + Channel* c = ServerInstance->FindChan(params[1]); if (u) { diff --git a/src/modules/m_spanningtree/time.cpp b/src/modules/m_spanningtree/time.cpp index 82a7fe62e..6fdcf8b53 100644 --- a/src/modules/m_spanningtree/time.cpp +++ b/src/modules/m_spanningtree/time.cpp @@ -31,20 +31,20 @@ bool TreeSocket::Time(const std::string &prefix, parameterlist ¶ms) if (params.size() == 2) { // someone querying our time? - if (this->ServerInstance->Config->ServerName == params[0] || this->ServerInstance->Config->GetSID() == params[0]) + if (ServerInstance->Config->ServerName == params[0] || ServerInstance->Config->GetSID() == params[0]) { - User* u = this->ServerInstance->FindNick(params[1]); + User* u = ServerInstance->FindNick(params[1]); if (u) { params.push_back(ConvToStr(ServerInstance->Time())); params[0] = prefix; - Utils->DoOneToOne(this->ServerInstance->Config->GetSID(),"TIME",params,params[0]); + Utils->DoOneToOne(ServerInstance->Config->GetSID(),"TIME",params,params[0]); } } else { // not us, pass it on - User* u = this->ServerInstance->FindNick(params[1]); + User* u = ServerInstance->FindNick(params[1]); if (u) Utils->DoOneToOne(prefix,"TIME",params,params[0]); } @@ -52,7 +52,7 @@ bool TreeSocket::Time(const std::string &prefix, parameterlist ¶ms) else if (params.size() == 3) { // a response to a previous TIME - User* u = this->ServerInstance->FindNick(params[1]); + User* u = ServerInstance->FindNick(params[1]); if ((u) && (IS_LOCAL(u))) { std::string sourceserv = Utils->FindServer(prefix)->GetName(); diff --git a/src/modules/m_spanningtree/treesocket.h b/src/modules/m_spanningtree/treesocket.h index a26e89f85..3c9484981 100644 --- a/src/modules/m_spanningtree/treesocket.h +++ b/src/modules/m_spanningtree/treesocket.h @@ -71,7 +71,6 @@ class TreeSocket : public BufferedSocket { SpanningTreeUtilities* Utils; /* Utility class */ std::string myhost; /* Canonical hostname */ - std::string in_buffer; /* Input buffer */ ServerState LinkState; /* Link state */ std::string InboundServerName; /* Server name sent to us by other side */ std::string InboundDescription; /* Server description (GECOS) sent to us by the other side */ @@ -80,10 +79,10 @@ class TreeSocket : public BufferedSocket int num_lost_servers; /* Servers lost in split */ time_t NextPing; /* Time when we are due to ping this server */ bool LastPingWasGood; /* Responded to last ping we sent? */ + std::string IP; std::string ModuleList; /* Required module list of other server from CAPAB */ std::string OptModuleList; /* Optional module list of other server from CAPAB */ std::map<std::string,std::string> CapKeys; /* CAPAB keys from other server */ - Module* Hook; /* I/O hooking module that we're attached to for this socket */ std::string ourchallenge; /* Challenge sent for challenge/response */ std::string theirchallenge; /* Challenge recv for challenge/response */ std::string OutboundPass; /* Outbound password */ @@ -101,13 +100,13 @@ class TreeSocket : public BufferedSocket * most of the action, and append a few of our own values * to it. */ - TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, std::string host, int port, unsigned long maxtime, const std::string &ServerName, const std::string &bindto, Autoconnect* myac, Module* HookMod = NULL); + TreeSocket(SpanningTreeUtilities* Util, std::string host, int port, unsigned long maxtime, const std::string &ServerName, const std::string &bindto, Autoconnect* myac, Module* HookMod = NULL); /** When a listening socket gives us a new file descriptor, * we must associate it with a socket without creating a new * connection. This constructor is used for this purpose. */ - TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, int newfd, char* ip, Autoconnect* myac, Module* HookMod = NULL); + TreeSocket(SpanningTreeUtilities* Util, int newfd, char* ip, Autoconnect* myac, Module* HookMod = NULL); /** Get link state */ @@ -137,10 +136,6 @@ class TreeSocket : public BufferedSocket */ void CleanNegotiationInfo(); - /** Return the module which we are hooking to for I/O encapsulation - */ - Module* GetHook(); - /** Destructor */ ~TreeSocket(); @@ -160,7 +155,7 @@ class TreeSocket : public BufferedSocket * to server docs on the inspircd.org site, the other side * will then send back its own server string. */ - virtual bool OnConnected(); + virtual void OnConnected(); /** Handle socket error event */ @@ -171,10 +166,6 @@ class TreeSocket : public BufferedSocket */ void SendError(const std::string &errormessage); - /** Handle socket disconnect event - */ - virtual int OnDisconnect(); - /** Recursively send the server tree with distances as hops. * This is used during network burst to inform the other server * (and any of ITS servers too) of what servers we know about. @@ -258,14 +249,9 @@ class TreeSocket : public BufferedSocket void DoBurst(TreeServer* s); /** This function is called when we receive data from a remote - * server. We buffer the data in a std::string (it doesnt stay - * there for long), reading using BufferedSocket::Read() which can - * read up to 16 kilobytes in one operation. - * - * IF THIS FUNCTION RETURNS FALSE, THE CORE CLOSES AND DELETES - * THE SOCKET OBJECT FOR US. + * server. */ - virtual bool OnDataReady(); + void OnDataReady(); /** Send one or more complete lines down the socket */ @@ -404,10 +390,9 @@ class TreeSocket : public BufferedSocket /** Handle socket timeout from connect() */ virtual void OnTimeout(); - - /** Handle socket close event + /** Handle server quit on close */ - virtual void OnClose(); + virtual void Close(); }; /* Used to validate the value lengths of multiple parameters for a command */ diff --git a/src/modules/m_spanningtree/treesocket1.cpp b/src/modules/m_spanningtree/treesocket1.cpp index d59364751..55fbc2c91 100644 --- a/src/modules/m_spanningtree/treesocket1.cpp +++ b/src/modules/m_spanningtree/treesocket1.cpp @@ -34,17 +34,18 @@ * most of the action, and append a few of our own values * to it. */ -TreeSocket::TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, std::string shost, int iport, unsigned long maxtime, const std::string &ServerName, const std::string &bindto, Autoconnect* myac, Module* HookMod) - : BufferedSocket(SI, shost, iport, maxtime, bindto), Utils(Util), Hook(HookMod), myautoconnect(myac) +TreeSocket::TreeSocket(SpanningTreeUtilities* Util, std::string shost, int iport, unsigned long maxtime, const std::string &ServerName, const std::string &bindto, Autoconnect* myac, Module* HookMod) + : Utils(Util), IP(shost), myautoconnect(myac) { - age = SI->Time(); + age = ServerInstance->Time(); myhost = ServerName; capab_phase = 0; proto_version = 0; LinkState = CONNECTING; + DoConnect(shost, iport, maxtime, bindto); Utils->timeoutlist[this] = std::pair<std::string, int>(ServerName, maxtime); - if (Hook) - BufferedSocketHookRequest(this, (Module*)Utils->Creator, Hook).Send(); + if (HookMod) + BufferedSocketHookRequest(this, Utils->Creator, HookMod).Send(); hstimer = NULL; } @@ -52,18 +53,18 @@ TreeSocket::TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, std::string sh * we must associate it with a socket without creating a new * connection. This constructor is used for this purpose. */ -TreeSocket::TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, int newfd, char* ip, Autoconnect* myac, Module* HookMod) - : BufferedSocket(SI, newfd, ip), Utils(Util), Hook(HookMod), myautoconnect(myac) +TreeSocket::TreeSocket(SpanningTreeUtilities* Util, int newfd, char* ip, Autoconnect* myac, Module* HookMod) + : BufferedSocket(newfd), Utils(Util), IP(ip), myautoconnect(myac) { - age = SI->Time(); + age = ServerInstance->Time(); LinkState = WAIT_AUTH_1; capab_phase = 0; proto_version = 0; /* If we have a transport module hooked to the parent, hook the same module to this * socket, and set a timer waiting for handshake before we send CAPAB etc. */ - if (Hook) - BufferedSocketHookRequest(this, (Module*)Utils->Creator, Hook).Send(); + if (HookMod) + BufferedSocketHookRequest(this, Utils->Creator, HookMod).Send(); hstimer = new HandshakeTimer(ServerInstance, this, &(Utils->LinkBlocks[0]), this->Utils, 1); ServerInstance->Timers->AddTimer(hstimer); @@ -77,11 +78,6 @@ ServerState TreeSocket::GetLinkState() return this->LinkState; } -Module* TreeSocket::GetHook() -{ - return this->Hook; -} - void TreeSocket::CleanNegotiationInfo() { ModuleList.clear(); @@ -94,8 +90,8 @@ void TreeSocket::CleanNegotiationInfo() TreeSocket::~TreeSocket() { - if (Hook) - BufferedSocketUnhookRequest(this, (Module*)Utils->Creator, Hook).Send(); + if (GetIOHook()) + BufferedSocketUnhookRequest(this, Utils->Creator, GetIOHook()).Send(); if (hstimer) ServerInstance->Timers->DelTimer(hstimer); Utils->timeoutlist.erase(this); @@ -107,7 +103,7 @@ TreeSocket::~TreeSocket() * to server docs on the inspircd.org site, the other side * will then send back its own server string. */ -bool TreeSocket::OnConnected() +void TreeSocket::OnConnected() { if (this->LinkState == CONNECTING) { @@ -116,25 +112,17 @@ bool TreeSocket::OnConnected() { if (x->Name == this->myhost) { - ServerInstance->SNO->WriteToSnoMask('l', "Connection to \2%s\2[%s] started.", myhost.c_str(), (x->HiddenFromStats ? "<hidden>" : this->GetIP().c_str())); - if (Hook) - { - BufferedSocketHookRequest(this, (Module*)Utils->Creator, Hook).Send(); - ServerInstance->SNO->WriteToSnoMask('l', "Connection to \2%s\2[%s] using transport \2%s\2", myhost.c_str(), (x->HiddenFromStats ? "<hidden>" : this->GetIP().c_str()), - x->Hook.c_str()); - } + ServerInstance->SNO->WriteToSnoMask('l', "Connection to \2%s\2[%s] started.", myhost.c_str(), (x->HiddenFromStats ? "<hidden>" : this->IP.c_str())); this->OutboundPass = x->SendPass; - - /* found who we're supposed to be connecting to, send the neccessary gubbins. */ - if (this->GetHook()) + if (GetIOHook()) { + ServerInstance->SNO->WriteToSnoMask('l', "Connection to \2%s\2[%s] using transport \2%s\2", myhost.c_str(), (x->HiddenFromStats ? "<hidden>" : this->IP.c_str()), x->Hook.c_str()); hstimer = new HandshakeTimer(ServerInstance, this, &(*x), this->Utils, 1); ServerInstance->Timers->AddTimer(hstimer); } else this->SendCapabilities(1); - - return true; + return; } } } @@ -144,7 +132,6 @@ bool TreeSocket::OnConnected() * and rather harmless. */ ServerInstance->SNO->WriteToSnoMask('l', "Connection to \2%s\2 lost link tag(!)", myhost.c_str()); - return true; } void TreeSocket::OnError(BufferedSocketError e) @@ -174,21 +161,11 @@ void TreeSocket::OnError(BufferedSocketError e) } } -int TreeSocket::OnDisconnect() -{ - /* For the same reason as above, we don't - * handle OnDisconnect() - */ - return true; -} - void TreeSocket::SendError(const std::string &errormessage) { /* Display the error locally as well as sending it remotely */ - ServerInstance->SNO->WriteToSnoMask('l', "Sent \2ERROR\2 to %s: %s", (this->InboundServerName.empty() ? this->GetIP().c_str() : this->InboundServerName.c_str()), errormessage.c_str()); - this->WriteLine("ERROR :"+errormessage); - /* One last attempt to make sure the error reaches its target */ - this->FlushWriteBuffer(); + ServerInstance->SNO->WriteToSnoMask('l', "Sent \2ERROR\2 to %s: %s", (this->InboundServerName.empty() ? this->IP.c_str() : this->InboundServerName.c_str()), errormessage.c_str()); + WriteLine("ERROR :"+errormessage); } /** This function forces this server to quit, removing this server @@ -232,12 +209,12 @@ void TreeSocket::Squit(TreeServer* Current, const std::string &reason) Utils->DoOneToAllButSender(Current->GetParent()->GetName(),"SQUIT",params,Current->GetName()); if (Current->GetParent() == Utils->TreeRoot) { - this->ServerInstance->SNO->WriteToSnoMask('l', "Server \002"+Current->GetName()+"\002 split: "+reason); + ServerInstance->SNO->WriteToSnoMask('l', "Server \002"+Current->GetName()+"\002 split: "+reason); LocalSquit = true; } else { - this->ServerInstance->SNO->WriteToSnoMask('L', "Server \002"+Current->GetName()+"\002 split from server \002"+Current->GetParent()->GetName()+"\002 with reason: "+reason); + ServerInstance->SNO->WriteToSnoMask('L', "Server \002"+Current->GetName()+"\002 split from server \002"+Current->GetParent()->GetName()+"\002 with reason: "+reason); } num_lost_servers = 0; num_lost_users = 0; @@ -247,56 +224,41 @@ void TreeSocket::Squit(TreeServer* Current, const std::string &reason) Current->GetParent()->DelChild(Current); delete Current; if (LocalSquit) - this->ServerInstance->SNO->WriteToSnoMask('l', "Netsplit complete, lost \002%d\002 users on \002%d\002 servers.", num_lost_users, num_lost_servers); + ServerInstance->SNO->WriteToSnoMask('l', "Netsplit complete, lost \002%d\002 users on \002%d\002 servers.", num_lost_users, num_lost_servers); else - this->ServerInstance->SNO->WriteToSnoMask('L', "Netsplit complete, lost \002%d\002 users on \002%d\002 servers.", num_lost_users, num_lost_servers); + ServerInstance->SNO->WriteToSnoMask('L', "Netsplit complete, lost \002%d\002 users on \002%d\002 servers.", num_lost_users, num_lost_servers); } else ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"Squit from unknown server"); } /** This function is called when we receive data from a remote - * server. We buffer the data in a std::string (it doesnt stay - * there for long), reading using BufferedSocket::Read() which can - * read up to 16 kilobytes in one operation. - * - * IF THIS FUNCTION RETURNS FALSE, THE CORE CLOSES AND DELETES - * THE SOCKET OBJECT FOR US. + * server. */ -bool TreeSocket::OnDataReady() +void TreeSocket::OnDataReady() { - const char* data = this->Read(); - /* Check that the data read is a valid pointer and it has some content */ - if (data && *data) + Utils->Creator->loopCall = true; + /* While there is at least one new line in the buffer, + * do something useful (we hope!) with it. + */ + while (recvq.find("\n") != std::string::npos) { - this->in_buffer.append(data); - Utils->Creator->loopCall = true; - /* While there is at least one new line in the buffer, - * do something useful (we hope!) with it. + std::string ret = recvq.substr(0,recvq.find("\n")-1); + recvq = recvq.substr(recvq.find("\n")+1,recvq.length()-recvq.find("\n")); + /* Use rfind here not find, as theres more + * chance of the \r being near the end of the + * string, not the start. */ - while (in_buffer.find("\n") != std::string::npos) + if (ret.find("\r") != std::string::npos) + ret = recvq.substr(0,recvq.find("\r")-1); + /* Process this one, abort if it + * didnt return true. + */ + if (!this->ProcessLine(ret)) { - std::string ret = in_buffer.substr(0,in_buffer.find("\n")-1); - in_buffer = in_buffer.substr(in_buffer.find("\n")+1,in_buffer.length()-in_buffer.find("\n")); - /* Use rfind here not find, as theres more - * chance of the \r being near the end of the - * string, not the start. - */ - if (ret.find("\r") != std::string::npos) - ret = in_buffer.substr(0,in_buffer.find("\r")-1); - /* Process this one, abort if it - * didnt return true. - */ - if (!this->ProcessLine(ret)) - { - return false; - } + SetError("ProcessLine returned false"); + break; } - Utils->Creator->loopCall = false; - return true; } - /* EAGAIN returns an empty but non-NULL string, so this - * evaluates to TRUE for EAGAIN but to FALSE for EOF. - */ - return (data && !*data); + Utils->Creator->loopCall = false; } diff --git a/src/modules/m_spanningtree/treesocket2.cpp b/src/modules/m_spanningtree/treesocket2.cpp index 793802781..cf537f05b 100644 --- a/src/modules/m_spanningtree/treesocket2.cpp +++ b/src/modules/m_spanningtree/treesocket2.cpp @@ -32,7 +32,7 @@ bool TreeSocket::Error(parameterlist ¶ms) { if (params.size() < 1) return false; - this->ServerInstance->SNO->WriteToSnoMask('l',"ERROR from %s: %s",(!InboundServerName.empty() ? InboundServerName.c_str() : myhost.c_str()),params[0].c_str()); + ServerInstance->SNO->WriteToSnoMask('l',"ERROR from %s: %s",(!InboundServerName.empty() ? InboundServerName.c_str() : myhost.c_str()),params[0].c_str()); /* we will return false to cause the socket to close. */ return false; } @@ -126,9 +126,7 @@ bool TreeSocket::ProcessLine(std::string &line) } else { - // XXX ...wtf. - irc::string error = "Invalid command in negotiation phase: " + command; - this->SendError(assign(error)); + this->SendError(std::string("Invalid command in negotiation phase: ") + command.c_str()); return false; } break; @@ -171,7 +169,7 @@ bool TreeSocket::ProcessLine(std::string &line) Link* lnk = Utils->FindLink(InboundServerName); - Node = new TreeServer(this->Utils, this->ServerInstance, InboundServerName, InboundDescription, InboundSID, Utils->TreeRoot, this, lnk ? lnk->Hidden : false); + Node = new TreeServer(this->Utils, ServerInstance, InboundServerName, InboundDescription, InboundSID, Utils->TreeRoot, this, lnk ? lnk->Hidden : false); Utils->TreeRoot->AddChild(Node); parameterlist sparams; @@ -242,7 +240,7 @@ bool TreeSocket::ProcessLine(std::string &line) */ std::string direction = prefix; - User *t = this->ServerInstance->FindUUID(prefix); + User *t = ServerInstance->FindUUID(prefix); if (t) { /* Find UID */ @@ -316,7 +314,7 @@ bool TreeSocket::ProcessLine(std::string &line) } else if ((command == "NOTICE" || command == "PRIVMSG") && (Utils->IsServer(prefix))) { - return this->ServerMessage(assign(command), prefix, params, sourceserv); + return ServerMessage(assign(command), prefix, params, sourceserv); } else if (command == "STATS") { @@ -487,7 +485,7 @@ bool TreeSocket::ProcessLine(std::string &line) // Set prefix server as bursting if (!ServerSource) { - this->ServerInstance->SNO->WriteToSnoMask('l', "WTF: Got BURST from a nonexistant server(?): %s", (ServerSource ? ServerSource->GetName().c_str() : prefix.c_str())); + ServerInstance->SNO->WriteToSnoMask('l', "WTF: Got BURST from a nonexistant server(?): %s", (ServerSource ? ServerSource->GetName().c_str() : prefix.c_str())); return false; } @@ -498,7 +496,7 @@ bool TreeSocket::ProcessLine(std::string &line) { if (!ServerSource) { - this->ServerInstance->SNO->WriteToSnoMask('l', "WTF: Got ENDBURST from a nonexistant server(?): %s", (ServerSource ? ServerSource->GetName().c_str() : prefix.c_str())); + ServerInstance->SNO->WriteToSnoMask('l', "WTF: Got ENDBURST from a nonexistant server(?): %s", (ServerSource ? ServerSource->GetName().c_str() : prefix.c_str())); return false; } @@ -515,7 +513,7 @@ bool TreeSocket::ProcessLine(std::string &line) * Not a special s2s command. Emulate the user doing it. * This saves us having a huge ugly command parser again. */ - User* who = this->ServerInstance->FindUUID(prefix); + User* who = ServerInstance->FindUUID(prefix); if (ServerSource) { @@ -546,7 +544,7 @@ bool TreeSocket::ProcessLine(std::string &line) * On nick messages, check that the nick doesnt already exist here. * If it does, perform collision logic. */ - User* x = this->ServerInstance->FindNickOnly(params[0]); + User* x = ServerInstance->FindNickOnly(params[0]); if ((x) && (x != who)) { int collideret = 0; @@ -564,7 +562,7 @@ bool TreeSocket::ProcessLine(std::string &line) } } - switch (this->ServerInstance->CallCommandHandler(command.c_str(), params, who)) + switch (ServerInstance->CallCommandHandler(command.c_str(), params, who)) { case CMD_INVALID: /* @@ -607,13 +605,15 @@ void TreeSocket::OnTimeout() { if (this->LinkState == CONNECTING) { - this->ServerInstance->SNO->WriteToSnoMask('l', "CONNECT: Connection to \002%s\002 timed out.", myhost.c_str()); + ServerInstance->SNO->WriteToSnoMask('l', "CONNECT: Connection to \002%s\002 timed out.", myhost.c_str()); Utils->DoFailOver(myautoconnect); } } -void TreeSocket::OnClose() +void TreeSocket::Close() { + this->BufferedSocket::Close(); + // Test fix for big fuckup if (this->LinkState != CONNECTED) return; @@ -634,10 +634,10 @@ void TreeSocket::OnClose() if (!quitserver.empty()) { - this->ServerInstance->SNO->WriteToSnoMask('l', "Connection to '\2%s\2' failed.",quitserver.c_str()); + ServerInstance->SNO->WriteToSnoMask('l', "Connection to '\2%s\2' failed.",quitserver.c_str()); time_t server_uptime = ServerInstance->Time() - this->age; if (server_uptime) - this->ServerInstance->SNO->WriteToSnoMask('l', "Connection to '\2%s\2' was established for %s", quitserver.c_str(), Utils->Creator->TimeToStr(server_uptime).c_str()); + ServerInstance->SNO->WriteToSnoMask('l', "Connection to '\2%s\2' was established for %s", quitserver.c_str(), Utils->Creator->TimeToStr(server_uptime).c_str()); } } diff --git a/src/modules/m_spanningtree/uid.cpp b/src/modules/m_spanningtree/uid.cpp index b7c13b5f8..0f0e75a1d 100644 --- a/src/modules/m_spanningtree/uid.cpp +++ b/src/modules/m_spanningtree/uid.cpp @@ -64,9 +64,9 @@ bool TreeSocket::ParseUID(const std::string &source, parameterlist ¶ms) } /* check for collision */ - user_hash::iterator iter = this->ServerInstance->Users->clientlist->find(params[2]); + user_hash::iterator iter = ServerInstance->Users->clientlist->find(params[2]); - if (iter != this->ServerInstance->Users->clientlist->end()) + if (iter != ServerInstance->Users->clientlist->end()) { /* * Nick collision. @@ -87,19 +87,19 @@ bool TreeSocket::ParseUID(const std::string &source, parameterlist ¶ms) User* _new = NULL; try { - _new = new User(this->ServerInstance, params[0]); + _new = new User(ServerInstance, params[0]); } catch (...) { this->SendError("Protocol violation - Duplicate UUID '" + params[0] + "' on introduction of new user"); return false; } - (*(this->ServerInstance->Users->clientlist))[params[2]] = _new; + (*(ServerInstance->Users->clientlist))[params[2]] = _new; _new->SetFd(FD_MAGIC_NUMBER); _new->nick.assign(params[2], 0, MAXBUF); _new->host.assign(params[3], 0, 64); _new->dhost.assign(params[4], 0, 64); - _new->server = this->ServerInstance->FindServerNamePtr(remoteserver->GetName().c_str()); + _new->server = ServerInstance->FindServerNamePtr(remoteserver->GetName().c_str()); _new->ident.assign(params[5], 0, MAXBUF); _new->fullname.assign(params[params.size() - 1], 0, MAXBUF); _new->registered = REG_ALL; @@ -164,11 +164,11 @@ bool TreeSocket::ParseUID(const std::string &source, parameterlist ¶ms) bool dosend = true; - if ((this->Utils->quiet_bursts && remoteserver->bursting) || this->ServerInstance->SilentULine(_new->server)) + if ((this->Utils->quiet_bursts && remoteserver->bursting) || ServerInstance->SilentULine(_new->server)) dosend = false; if (dosend) - this->ServerInstance->SNO->WriteToSnoMask('C',"Client connecting at %s: %s!%s@%s [%s] [%s]", _new->server, _new->nick.c_str(), _new->ident.c_str(), _new->host.c_str(), _new->GetIPString(), _new->fullname.c_str()); + ServerInstance->SNO->WriteToSnoMask('C',"Client connecting at %s: %s!%s@%s [%s] [%s]", _new->server, _new->nick.c_str(), _new->ident.c_str(), _new->host.c_str(), _new->GetIPString(), _new->fullname.c_str()); params[params.size() - 1] = ":" + params[params.size() - 1]; Utils->DoOneToAllButSender(source, "UID", params, source); diff --git a/src/modules/m_spanningtree/utils.cpp b/src/modules/m_spanningtree/utils.cpp index b37aecc4b..8d3c55758 100644 --- a/src/modules/m_spanningtree/utils.cpp +++ b/src/modules/m_spanningtree/utils.cpp @@ -49,19 +49,18 @@ void ServerSocketListener::OnAcceptReady(int newsock) if (!found) { - this->ServerInstance->SNO->WriteToSnoMask('l', "Server connection from %s denied (no link blocks with that IP address)", ip); + ServerInstance->SNO->WriteToSnoMask('l', "Server connection from %s denied (no link blocks with that IP address)", ip); ServerInstance->SE->Close(newsock); return; } } - if (this->GetIOHook()) - { - this->GetIOHook()->OnRawSocketAccept(newsock, &client, &server); - } + /* we don't need to do anything with the pointer, creating it stores it in the necessary places */ + TreeSocket* ts = new TreeSocket(Utils, newsock, ip, NULL, Hook); + + if (Hook) + Hook->OnStreamSocketAccept(ts, &client, &server); - /* we don't need a pointer to this, creating it stores it in the necessary places */ - new TreeSocket(this->Utils, this->ServerInstance, newsock, ip, NULL, this->GetIOHook()); return; } @@ -73,7 +72,7 @@ void ServerSocketListener::OnAcceptReady(int newsock) */ TreeServer* SpanningTreeUtilities::FindServer(const std::string &ServerName) { - if (this->ServerInstance->IsSID(ServerName)) + if (ServerInstance->IsSID(ServerName)) return this->FindServerID(ServerName); server_hash::iterator iter = serverlist.find(ServerName.c_str()); @@ -150,12 +149,10 @@ bool SpanningTreeUtilities::IsServer(const std::string &ServerName) SpanningTreeUtilities::SpanningTreeUtilities(InspIRCd* Instance, ModuleSpanningTree* C) : ServerInstance(Instance), Creator(C) { - Bindings.clear(); - ServerInstance->Logs->Log("m_spanningtree",DEBUG,"***** Using SID for hash: %s *****", ServerInstance->Config->GetSID().c_str()); this->TreeRoot = new TreeServer(this, ServerInstance, ServerInstance->Config->ServerName, ServerInstance->Config->ServerDesc, ServerInstance->Config->GetSID()); - this->ServerUser = new FakeUser(ServerInstance, TreeRoot->GetID()); + ServerUser = new FakeUser(ServerInstance, TreeRoot->GetID()); this->ReadConfiguration(true); } @@ -182,7 +179,6 @@ SpanningTreeUtilities::~SpanningTreeUtilities() ServerUser->uuid = TreeRoot->GetID(); delete TreeRoot; delete ServerUser; - ServerInstance->BufferedSocketCull(); } void SpanningTreeUtilities::AddThisServer(TreeServer* server, TreeServerList &list) @@ -465,7 +461,6 @@ void SpanningTreeUtilities::ReadConfiguration(bool rebind) { delete Bindings[i]; } - ServerInstance->BufferedSocketCull(); Bindings.clear(); for (int j = 0; j < Conf->Enumerate("bind"); j++) @@ -498,7 +493,7 @@ void SpanningTreeUtilities::ReadConfiguration(bool rebind) } if (!transport.empty()) - listener->AddIOHook(hooks[transport.c_str()]); + listener->Hook = hooks[transport.c_str()]; Bindings.push_back(listener); } @@ -656,7 +651,7 @@ void SpanningTreeUtilities::DoFailOver(Autoconnect* x) { if (x->FailOver == x->Server) { - this->ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Some muppet configured the failover for server \002%s\002 to point at itself. Not following it!", x->Server.c_str()); + ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Some muppet configured the failover for server \002%s\002 to point at itself. Not following it!", x->Server.c_str()); return; } Link* TryThisOne = this->FindLink(x->FailOver.c_str()); @@ -669,13 +664,13 @@ void SpanningTreeUtilities::DoFailOver(Autoconnect* x) } else { - this->ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Trying failover link for \002%s\002: \002%s\002...", x->Server.c_str(), TryThisOne->Name.c_str()); + ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Trying failover link for \002%s\002: \002%s\002...", x->Server.c_str(), TryThisOne->Name.c_str()); Creator->ConnectServer(TryThisOne, NULL); } } else { - this->ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Invalid failover server specified for server \002%s\002, will not follow!", x->Server.c_str()); + ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Invalid failover server specified for server \002%s\002, will not follow!", x->Server.c_str()); } } } diff --git a/src/modules/m_spanningtree/utils.h b/src/modules/m_spanningtree/utils.h index 09c707131..1bdf127d8 100644 --- a/src/modules/m_spanningtree/utils.h +++ b/src/modules/m_spanningtree/utils.h @@ -47,8 +47,11 @@ class ServerSocketListener : public ListenSocketBase ServerSocketListener(InspIRCd* Instance, SpanningTreeUtilities *u, int port, char* addr) : ListenSocketBase(Instance, port, addr) { this->Utils = u; + Hook = NULL; } + Module* Hook; + virtual void OnAcceptReady(int nfd); }; diff --git a/src/modules/m_spanningtree/whois.cpp b/src/modules/m_spanningtree/whois.cpp index f12a7f109..79e2d7355 100644 --- a/src/modules/m_spanningtree/whois.cpp +++ b/src/modules/m_spanningtree/whois.cpp @@ -28,13 +28,13 @@ bool TreeSocket::Whois(const std::string &prefix, parameterlist ¶ms) { if (params.size() < 1) return true; - User* u = this->ServerInstance->FindNick(prefix); + User* u = ServerInstance->FindNick(prefix); if (u) { // an incoming request if (params.size() == 1) { - User* x = this->ServerInstance->FindNick(params[0]); + User* x = ServerInstance->FindNick(params[0]); if ((x) && (IS_LOCAL(x))) { char signon[MAXBUF]; @@ -58,7 +58,7 @@ bool TreeSocket::Whois(const std::string &prefix, parameterlist ¶ms) else if (params.size() == 3) { std::string who_did_the_whois = params[0]; - User* who_to_send_to = this->ServerInstance->FindNick(who_did_the_whois); + User* who_to_send_to = ServerInstance->FindNick(who_did_the_whois); if ((who_to_send_to) && (IS_LOCAL(who_to_send_to))) { // an incoming reply to a whois we sent out diff --git a/src/socket.cpp b/src/socket.cpp index ccae48a6d..cc9cb79b9 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -273,7 +273,7 @@ std::string irc::sockets::satouser(const irc::sockets::sockaddrs* sa) { return std::string(buffer); } -int irc::sockets::sa_size(irc::sockets::sockaddrs& sa) +int irc::sockets::sa_size(const irc::sockets::sockaddrs& sa) { if (sa.sa.sa_family == AF_INET) return sizeof(sa.in4); diff --git a/src/socketengine.cpp b/src/socketengine.cpp index af2f1b169..c0ae3f278 100644 --- a/src/socketengine.cpp +++ b/src/socketengine.cpp @@ -43,35 +43,7 @@ EventHandler::EventHandler() { - this->IOHook = NULL; -} - -bool EventHandler::AddIOHook(Module *IOHooker) -{ - if (this->IOHook) - return false; - - this->IOHook = IOHooker; - return true; -} - -bool EventHandler::DelIOHook() -{ - if (!this->IOHook) - return false; - - this->IOHook = NULL; - return true; -} - -Module *EventHandler::GetIOHook() -{ - return this->IOHook; -} - -int EventHandler::GetFd() -{ - return this->fd; + fd = -1; } void EventHandler::SetFd(int FD) @@ -79,21 +51,7 @@ void EventHandler::SetFd(int FD) this->fd = FD; } -bool EventHandler::Readable() -{ - return true; -} - -bool EventHandler::Writeable() -{ - return false; -} - -void SocketEngine::WantWrite(EventHandler* eh) -{ -} - -SocketEngine::SocketEngine(InspIRCd* Instance) : ServerInstance(Instance) +SocketEngine::SocketEngine() { TotalEvents = WriteEvents = ReadEvents = ErrorEvents = 0; lastempty = ServerInstance->Time(); @@ -104,11 +62,6 @@ SocketEngine::~SocketEngine() { } -bool SocketEngine::AddFd(EventHandler* eh) -{ - return true; -} - bool SocketEngine::HasFd(int fd) { if ((fd < 0) || (fd > MAX_DESCRIPTORS)) @@ -123,11 +76,6 @@ EventHandler* SocketEngine::GetRef(int fd) return ref[fd]; } -bool SocketEngine::DelFd(EventHandler* eh, bool force) -{ - return true; -} - int SocketEngine::GetMaxFds() { return 0; @@ -143,11 +91,6 @@ int SocketEngine::DispatchEvents() return 0; } -std::string SocketEngine::GetName() -{ - return "misconfigured"; -} - bool SocketEngine::BoundsCheckFd(EventHandler* eh) { if (!eh) diff --git a/src/socketengines/socketengine_epoll.cpp b/src/socketengines/socketengine_epoll.cpp index 1be0d7cd2..7fed6f250 100644 --- a/src/socketengines/socketengine_epoll.cpp +++ b/src/socketengines/socketengine_epoll.cpp @@ -16,7 +16,7 @@ #include "socketengines/socketengine_epoll.h" #include <ulimit.h> -EPollEngine::EPollEngine(InspIRCd* Instance) : SocketEngine(Instance) +EPollEngine::EPollEngine() { MAX_DESCRIPTORS = 0; // This is not a maximum, just a hint at the eventual number of sockets that may be polled. @@ -45,7 +45,7 @@ EPollEngine::~EPollEngine() delete[] events; } -bool EPollEngine::AddFd(EventHandler* eh) +bool EPollEngine::AddFd(EventHandler* eh, bool writeFirst) { int fd = eh->GetFd(); if ((fd < 0) || (fd > GetMaxFds() - 1)) @@ -68,7 +68,7 @@ bool EPollEngine::AddFd(EventHandler* eh) struct epoll_event ev; memset(&ev,0,sizeof(ev)); - eh->Readable() ? ev.events = EPOLLIN : ev.events = EPOLLOUT; + ev.events = writeFirst ? EPOLLOUT : EPOLLIN; ev.data.fd = fd; int i = epoll_ctl(EngineHandle, EPOLL_CTL_ADD, fd, &ev); if (i < 0) @@ -107,7 +107,6 @@ bool EPollEngine::DelFd(EventHandler* eh, bool force) struct epoll_event ev; memset(&ev,0,sizeof(ev)); - eh->Readable() ? ev.events = EPOLLIN : ev.events = EPOLLOUT; ev.data.fd = fd; int i = epoll_ctl(EngineHandle, EPOLL_CTL_DEL, fd, &ev); diff --git a/src/socketengines/socketengine_iocp.cpp b/src/socketengines/socketengine_iocp.cpp index ee2e5afa1..3c3181909 100644 --- a/src/socketengines/socketengine_iocp.cpp +++ b/src/socketengines/socketengine_iocp.cpp @@ -15,7 +15,7 @@ #include "exitcodes.h" #include <mswsock.h> -IOCPEngine::IOCPEngine(InspIRCd * Instance) : SocketEngine(Instance) +IOCPEngine::IOCPEngine() { MAX_DESCRIPTORS = 10240; @@ -47,7 +47,7 @@ IOCPEngine::~IOCPEngine() delete[] ref; } -bool IOCPEngine::AddFd(EventHandler* eh) +bool IOCPEngine::AddFd(EventHandler* eh, bool writeFirst) { /* Does it at least look valid? */ if (!eh) @@ -92,7 +92,7 @@ bool IOCPEngine::AddFd(EventHandler* eh) ServerInstance->Logs->Log("SOCKET",DEBUG, "New fake fd: %u, real fd: %u, address 0x%p", *fake_fd, eh->GetFd(), eh); /* post a write event if there is data to be written */ - if(eh->Writeable()) + if(writeFirst) WantWrite(eh); /* we're all good =) */ diff --git a/src/socketengines/socketengine_kqueue.cpp b/src/socketengines/socketengine_kqueue.cpp index bf09eaf74..cbe3e959d 100644 --- a/src/socketengines/socketengine_kqueue.cpp +++ b/src/socketengines/socketengine_kqueue.cpp @@ -19,7 +19,7 @@ #include "socketengines/socketengine_kqueue.h" #include <sys/sysctl.h> -KQueueEngine::KQueueEngine(InspIRCd* Instance) : SocketEngine(Instance) +KQueueEngine::KQueueEngine() { MAX_DESCRIPTORS = 0; this->RecoverFromFork(); @@ -54,7 +54,7 @@ KQueueEngine::~KQueueEngine() delete[] ke_list; } -bool KQueueEngine::AddFd(EventHandler* eh) +bool KQueueEngine::AddFd(EventHandler* eh, bool writeFirst) { int fd = eh->GetFd(); @@ -79,7 +79,7 @@ bool KQueueEngine::AddFd(EventHandler* eh) return false; } - if (!eh->Readable()) { + if (writeFirst) { // ...and sometimes want to write WantWrite(eh); } diff --git a/src/socketengines/socketengine_poll.cpp b/src/socketengines/socketengine_poll.cpp index cee6a90cb..6d5ddb9f5 100644 --- a/src/socketengines/socketengine_poll.cpp +++ b/src/socketengines/socketengine_poll.cpp @@ -19,7 +19,7 @@ #include <sys/sysctl.h> #endif -PollEngine::PollEngine(InspIRCd* Instance) : SocketEngine(Instance) +PollEngine::PollEngine() { // Poll requires no special setup (which is nice). CurrentSetSize = 0; @@ -39,7 +39,7 @@ PollEngine::~PollEngine() delete[] events; } -bool PollEngine::AddFd(EventHandler* eh) +bool PollEngine::AddFd(EventHandler* eh, bool writeFirst) { int fd = eh->GetFd(); if ((fd < 0) || (fd > GetMaxFds() - 1)) @@ -65,13 +65,13 @@ bool PollEngine::AddFd(EventHandler* eh) fd_mappings[fd] = index; ref[index] = eh; events[index].fd = fd; - if (eh->Readable()) + if (writeFirst) { - events[index].events = POLLIN; + events[index].events = POLLOUT; } else { - events[index].events = POLLOUT; + events[index].events = POLLIN; } ServerInstance->Logs->Log("SOCKET", DEBUG,"New file descriptor: %d (%d; index %d)", fd, events[fd].events, index); diff --git a/src/socketengines/socketengine_ports.cpp b/src/socketengines/socketengine_ports.cpp index 5efa545b0..eb08839d0 100644 --- a/src/socketengines/socketengine_ports.cpp +++ b/src/socketengines/socketengine_ports.cpp @@ -17,7 +17,7 @@ #include "socketengines/socketengine_ports.h" #include <ulimit.h> -PortsEngine::PortsEngine(InspIRCd* Instance) : SocketEngine(Instance) +PortsEngine::PortsEngine() { MAX_DESCRIPTORS = 0; EngineHandle = port_create(); @@ -44,7 +44,7 @@ PortsEngine::~PortsEngine() delete[] events; } -bool PortsEngine::AddFd(EventHandler* eh) +bool PortsEngine::AddFd(EventHandler* eh, bool writeFirst) { int fd = eh->GetFd(); if ((fd < 0) || (fd > GetMaxFds() - 1)) @@ -57,7 +57,7 @@ bool PortsEngine::AddFd(EventHandler* eh) return false; ref[fd] = eh; - port_associate(EngineHandle, PORT_SOURCE_FD, fd, eh->Readable() ? POLLRDNORM : POLLWRNORM, eh); + port_associate(EngineHandle, PORT_SOURCE_FD, fd, writeFirst ? POLLWRNORM : POLLRDNORM, eh); ServerInstance->Logs->Log("SOCKET",DEBUG,"New file descriptor: %d", fd); CurrentSetSize++; diff --git a/src/socketengines/socketengine_select.cpp b/src/socketengines/socketengine_select.cpp index 8c41df11b..7f6a4e283 100644 --- a/src/socketengines/socketengine_select.cpp +++ b/src/socketengines/socketengine_select.cpp @@ -18,7 +18,7 @@ #include "socketengines/socketengine_select.h" -SelectEngine::SelectEngine(InspIRCd* Instance) : SocketEngine(Instance) +SelectEngine::SelectEngine() { MAX_DESCRIPTORS = FD_SETSIZE; EngineHandle = 0; @@ -34,7 +34,7 @@ SelectEngine::~SelectEngine() delete[] ref; } -bool SelectEngine::AddFd(EventHandler* eh) +bool SelectEngine::AddFd(EventHandler* eh, bool writeFirst) { int fd = eh->GetFd(); if ((fd < 0) || (fd > GetMaxFds() - 1)) @@ -50,6 +50,8 @@ bool SelectEngine::AddFd(EventHandler* eh) ref[fd] = eh; CurrentSetSize++; + writeable[eh->GetFd()] = writeFirst; + ServerInstance->Logs->Log("SOCKET",DEBUG,"New file descriptor: %d", fd); return true; } @@ -101,16 +103,11 @@ int SelectEngine::DispatchEvents() /* Populate the select FD set (this is why select sucks compared to epoll, kqueue, IOCP) */ for (std::set<int>::iterator a = fds.begin(); a != fds.end(); a++) { - if (ref[*a]->Readable()) - /* Read notifications */ - FD_SET (*a, &rfdset); - else - /* Write notifications */ - FD_SET (*a, &wfdset); - /* Explicitly one-time writeable */ if (writeable[*a]) FD_SET (*a, &wfdset); + else + FD_SET (*a, &rfdset); /* All sockets must receive error notifications regardless */ FD_SET (*a, &errfdset); diff --git a/src/stats.cpp b/src/stats.cpp index 40ee40b18..02cfeaa7c 100644 --- a/src/stats.cpp +++ b/src/stats.cpp @@ -254,7 +254,7 @@ void InspIRCd::DoStats(char statschar, User* user, string_list &results) for (std::vector<User*>::iterator n = this->Users->local_users.begin(); n != this->Users->local_users.end(); n++) { User* i = *n; - results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->dhost+"] "+ConvToStr(i->sendq.length())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(this->Time() - i->age)); + results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->dhost+"] "+ConvToStr(i->getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(this->Time() - i->age)); } break; @@ -264,7 +264,7 @@ void InspIRCd::DoStats(char statschar, User* user, string_list &results) for (std::vector<User*>::iterator n = this->Users->local_users.begin(); n != this->Users->local_users.end(); n++) { User* i = *n; - results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->GetIPString()+"] "+ConvToStr(i->sendq.length())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(this->Time() - i->age)); + results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->GetIPString()+"] "+ConvToStr(i->getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(this->Time() - i->age)); } break; diff --git a/src/threadengines/threadengine_pthread.cpp b/src/threadengines/threadengine_pthread.cpp index 6e32634c5..a4a47f8fa 100644 --- a/src/threadengines/threadengine_pthread.cpp +++ b/src/threadengines/threadengine_pthread.cpp @@ -65,8 +65,7 @@ class ThreadSignalSocket : public BufferedSocket { SocketThread* parent; public: - ThreadSignalSocket(SocketThread* p, InspIRCd* SI, int newfd) : - BufferedSocket(SI, newfd, const_cast<char*>("0.0.0.0")), parent(p) {} + ThreadSignalSocket(SocketThread* p, int newfd) : BufferedSocket(newfd), parent(p) {} ~ThreadSignalSocket() { @@ -77,13 +76,14 @@ class ThreadSignalSocket : public BufferedSocket eventfd_write(fd, 1); } - virtual bool OnDataReady() + void OnDataReady() { - eventfd_t data; - if (eventfd_read(fd, &data)) - return false; + recvq.clear(); parent->OnNotify(); - return true; + } + + void OnError(BufferedSocketError) + { } }; @@ -92,7 +92,7 @@ SocketThread::SocketThread(InspIRCd* SI) int fd = eventfd(0, O_NONBLOCK); if (fd < 0) throw new CoreException("Could not create pipe " + std::string(strerror(errno))); - signal.sock = new ThreadSignalSocket(this, SI, fd); + signal.sock = new ThreadSignalSocket(this, fd); } #else @@ -101,8 +101,8 @@ class ThreadSignalSocket : public BufferedSocket SocketThread* parent; int send_fd; public: - ThreadSignalSocket(SocketThread* p, InspIRCd* SI, int recvfd, int sendfd) : - BufferedSocket(SI, recvfd, const_cast<char*>("0.0.0.0")), parent(p), send_fd(sendfd) {} + ThreadSignalSocket(SocketThread* p, int recvfd, int sendfd) : + BufferedSocket(recvfd), parent(p), send_fd(sendfd) {} ~ThreadSignalSocket() { @@ -115,13 +115,14 @@ class ThreadSignalSocket : public BufferedSocket write(send_fd, &dummy, 1); } - virtual bool OnDataReady() + void OnDataReady() { - char data; - if (read(this->fd, &data, 1) <= 0) - return false; + recvq.clear(); parent->OnNotify(); - return true; + } + + void OnError(BufferedSocketError) + { } }; @@ -130,7 +131,7 @@ SocketThread::SocketThread(InspIRCd* SI) int fds[2]; if (pipe(fds)) throw new CoreException("Could not create pipe " + std::string(strerror(errno))); - signal.sock = new ThreadSignalSocket(this, SI, fds[0], fds[1]); + signal.sock = new ThreadSignalSocket(this, fds[0], fds[1]); } #endif diff --git a/src/threadengines/threadengine_win32.cpp b/src/threadengines/threadengine_win32.cpp index 5c62b5081..fab75699e 100644 --- a/src/threadengines/threadengine_win32.cpp +++ b/src/threadengines/threadengine_win32.cpp @@ -55,20 +55,15 @@ class ThreadSignalSocket : public BufferedSocket { SocketThread* parent; public: - ThreadSignalSocket(SocketThread* t, InspIRCd* SI, int newfd, const char* ip) - : BufferedSocket(SI, newfd, ip), parent(t) + ThreadSignalSocket(SocketThread* t, int newfd) + : BufferedSocket(newfd), parent(t) { } - virtual bool OnDataReady() + void OnDataReady() { - char data = 0; - if (ServerInstance->SE->Recv(this, &data, 1, 0) > 0) - { - parent->OnNotify(); - return true; - } - return false; + recvq.clear(); + parent->OnNotify(); } }; @@ -92,7 +87,7 @@ SocketThread::SocketThread(InspIRCd* SI) int nfd = accept(listenFD); if (nfd < 0) throw CoreException("Could not create ITC pipe"); - new ThreadSignalSocket(parent, ServerInstance, nfd, "127.0.0.1"); + new ThreadSignalSocket(parent, nfd); closesocket(listenFD); SI->SE->Blocking(connFD); diff --git a/src/usermanager.cpp b/src/usermanager.cpp index b9eff5a39..6d04bdff7 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -46,7 +46,7 @@ void UserManager::AddUser(InspIRCd* Instance, int socket, ClientListenSocket* vi { try { - New->GetIOHook()->OnRawSocketAccept(socket, client, server); + New->GetIOHook()->OnStreamSocketAccept(New, client, server); } catch (CoreException& modexcept) { @@ -201,24 +201,18 @@ void UserManager::QuitUser(User *user, const std::string &quitreason, const char FOREACH_MOD_I(ServerInstance,I_OnUserDisconnect,OnUserDisconnect(user)); - user->UpdateNickHash(user->uuid.c_str()); - - user_hash::iterator iter = this->clientlist->find(user->uuid); - if (user->registered != REG_ALL) if (ServerInstance->Users->unregistered_count) ServerInstance->Users->unregistered_count--; if (IS_LOCAL(user)) { - if (!user->sendq.empty()) - user->FlushWriteBuf(); - + user->DoWrite(); if (user->GetIOHook()) { try { - user->GetIOHook()->OnRawSocketClose(user->GetFd()); + user->GetIOHook()->OnStreamSocketClose(user); } catch (CoreException& modexcept) { @@ -227,7 +221,9 @@ void UserManager::QuitUser(User *user, const std::string &quitreason, const char } ServerInstance->SE->DelFd(user); - user->CloseSocket(); + user->Close(); + // user->Close() will set fd to -1; this breaks IS_LOCAL. Fix + user->SetFd(INT_MAX); } /* @@ -255,19 +251,12 @@ void UserManager::QuitUser(User *user, const std::string &quitreason, const char user->AddToWhoWas(); } + user_hash::iterator iter = this->clientlist->find(user->nick); + if (iter != this->clientlist->end()) this->clientlist->erase(iter); else ServerInstance->Logs->Log("USERS", DEBUG, "iter == clientlist->end, can't remove them from hash... problematic.."); - - if (IS_LOCAL(user)) - { - std::vector<User*>::iterator x = find(local_users.begin(),local_users.end(),user); - if (x != local_users.end()) - local_users.erase(x); - else - ServerInstance->Logs->Log("USERS", DEBUG, "Failed to remove user from vector"); - } } diff --git a/src/userprocess.cpp b/src/userprocess.cpp index 4fcf87f66..b150f2828 100644 --- a/src/userprocess.cpp +++ b/src/userprocess.cpp @@ -36,102 +36,6 @@ void FloodQuitUserHandler::Call(User* current) } } -void ProcessUserHandler::Call(User* cu) -{ - int result = EAGAIN; - - if (cu->GetFd() == FD_MAGIC_NUMBER) - return; - - char* ReadBuffer = Server->GetReadBuffer(); - - if (cu->GetIOHook()) - { - int result2 = 0; - int MOD_RESULT = 0; - - try - { - MOD_RESULT = cu->GetIOHook()->OnRawSocketRead(cu->GetFd(), ReadBuffer, Server->Config->NetBufferSize, result2); - } - catch (CoreException& modexcept) - { - Server->Logs->Log("USERS",DEBUG, "%s threw an exception: %s", modexcept.GetSource(), modexcept.GetReason()); - } - - if (MOD_RESULT < 0) - { - result = -EAGAIN; - } - else - { - result = result2; - } - } - else - { - result = cu->ReadData(ReadBuffer, Server->Config->NetBufferSize); - } - - if ((result) && (result != -EAGAIN)) - { - User *current; - int currfd; - - Server->stats->statsRecv += result; - /* - * perform a check on the raw buffer as an array (not a string!) to remove - * character 0 which is illegal in the RFC - replace them with spaces. - */ - - for (int checker = 0; checker < result; checker++) - { - if (ReadBuffer[checker] == 0) - ReadBuffer[checker] = ' '; - } - - if (result > 0) - ReadBuffer[result] = '\0'; - - current = cu; - currfd = current->GetFd(); - - // add the data to the users buffer - if (result > 0) - { - if (!current->AddBuffer(ReadBuffer)) - { - // AddBuffer returned false, theres too much data in the user's buffer and theyre up to no good. - Server->FloodQuitUser(current); - return; - } - - /* If user is over penalty, dont process here, just build up */ - if (current->Penalty < 10) - Server->Parser->DoLines(current); - - return; - } - - if ((result == -1) && (errno != EAGAIN) && (errno != EINTR)) - { - Server->Users->QuitUser(cu, errno ? strerror(errno) : "EOF from client"); - return; - } - } - - // result EAGAIN means nothing read - else if ((result == EAGAIN) || (result == -EAGAIN)) - { - /* do nothing */ - } - else if (result == 0) - { - Server->Users->QuitUser(cu, "Connection closed"); - return; - } -} - /** * This function is called once a second from the mainloop. * It is intended to do background checking on all the user structs, e.g. @@ -154,8 +58,12 @@ void InspIRCd::DoBackgroundUserStuff() if (curr->Penalty) { curr->Penalty--; - if (curr->Penalty < 10) - Parser->DoLines(curr, true); + curr->OnDataReady(); + } + + if (curr->getSendQSize() == 0) + { + FOREACH_MOD(I_OnBufferFlushed,OnBufferFlushed(curr)); } switch (curr->registered) diff --git a/src/users.cpp b/src/users.cpp index fd0c168d9..5d6b1a01a 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -216,12 +216,8 @@ User::User(InspIRCd* Instance, const std::string &uid) fd = -1; server_sa.sa.sa_family = AF_UNSPEC; client_sa.sa.sa_family = AF_UNSPEC; - recvq.clear(); - sendq.clear(); MyClass = NULL; AllowedPrivs = AllowedOperCommands = NULL; - chans.clear(); - invites.clear(); if (uid.empty()) uuid.assign(Instance->GetUID(), 0, UUID_LENGTH - 1); @@ -309,15 +305,6 @@ const std::string& User::MakeHostIP() return this->cached_hostip; } -void User::CloseSocket() -{ - if (this->fd > -1) - { - ServerInstance->SE->Shutdown(this, 2); - ServerInstance->SE->Close(this); - } -} - const std::string User::GetFullHost() { if (!this->cached_fullhost.empty()) @@ -352,21 +339,6 @@ char* User::MakeWildHost() return nresult; } -int User::ReadData(void* buffer, size_t size) -{ - if (IS_LOCAL(this)) - { -#ifndef WIN32 - return read(this->fd, buffer, size); -#else - return recv(this->fd, (char*)buffer, size, 0); -#endif - } - else - return 0; -} - - const std::string User::GetFullRealHost() { if (!this->cached_fullrealhost.empty()) @@ -540,123 +512,60 @@ bool User::HasPrivPermission(const std::string &privstr, bool noisy) return false; } -bool User::AddBuffer(const std::string &a) +void User::OnDataReady() { - std::string::size_type start = 0; - std::string::size_type i = a.find('\r'); - - /* - * The old implementation here took a copy, and rfind() on \r, removing as it found them, before - * copying a second time onto the recvq. That's ok, but involves three copies minimum (recv() to buffer, - * buffer to here, here to recvq) - The new method now copies twice (recv() to buffer, buffer to recvq). - * - * We use find() instead of rfind() for clarity, however unlike the old code, our scanning of the string is - * contiguous: as we specify a startpoint, we never see characters we have scanned previously, making this - * marginally faster in cases with a number of \r hidden early on in the buffer. - * - * How it works: - * Start at first pos of string, find first \r, append everything in the chunk (excluding \r) to recvq. Set - * i ahead of the \r, search for next \r, add next chunk to buffer... repeat. - * -- w00t (7 may, 2008) - */ - if (i == std::string::npos) - { - // no \r that we need to dance around, just add to buffer - recvq.append(a); - } - else - { - // While we can find the end of a chunk to add - while (i != std::string::npos) - { - // Append the chunk that we have - recvq.append(a, start, (i - start)); - - // Start looking for the next one - start = i + 1; - i = a.find('\r', start); - } - - if (start != a.length()) - { - /* - * This is here to catch a corner case when we get something like: - * NICK w0 - * 0t\r\nU - * SER ... - * in successive calls to us. - * - * Without this conditional, the 'U' on the second case will be dropped, - * which is most *certainly* not the behaviour we want! - * -- w00t - */ - recvq.append(a, start, (a.length() - start)); - } - } + if (quitting) + return; - if (this->MyClass && !this->HasPrivPermission("users/flood/increased-buffers") && recvq.length() > this->MyClass->GetRecvqMax()) + if (MyClass && !HasPrivPermission("users/flood/increased-buffers") && recvq.length() > MyClass->GetRecvqMax()) { ServerInstance->Users->QuitUser(this, "RecvQ exceeded"); - ServerInstance->SNO->WriteToSnoMask('a', "User %s RecvQ of %lu exceeds connect class maximum of %lu",this->nick.c_str(),(unsigned long int)recvq.length(),this->MyClass->GetRecvqMax()); - return false; + ServerInstance->SNO->WriteToSnoMask('a', "User %s RecvQ of %lu exceeds connect class maximum of %lu", + nick.c_str(), (unsigned long)recvq.length(), MyClass->GetRecvqMax()); } - return true; -} - -bool User::BufferIsReady() -{ - return (recvq.find('\n') != std::string::npos); -} - -void User::ClearBuffer() -{ - recvq.clear(); -} - -std::string User::GetBuffer() -{ - try + while (this->Penalty < 10) { - if (recvq.empty()) - return ""; - - /* Strip any leading \r or \n off the string. - * Usually there are only one or two of these, - * so its is computationally cheap to do. - */ - std::string::iterator t = recvq.begin(); - while (t != recvq.end() && (*t == '\r' || *t == '\n')) - { - recvq.erase(t); - t = recvq.begin(); - } - - for (std::string::iterator x = recvq.begin(); x != recvq.end(); x++) + std::string line; + line.reserve(MAXBUF); + std::string::size_type qpos = 0; + while (qpos < recvq.length()) { - /* Find the first complete line, return it as the - * result, and leave the recvq as whats left - */ - if (*x == '\n') + char c = recvq[qpos++]; + switch (c) { - std::string ret = std::string(recvq.begin(), x); - recvq.erase(recvq.begin(), x + 1); - return ret; + case '\0': + c = ' '; + break; + case '\r': + continue; + case '\n': + goto eol_found; } + if (line.length() < MAXBUF - 2) + line.push_back(c); } - return ""; - } + // if we got here, the recvq ran out before we found a newline + return; +eol_found: + // just found a newline. Terminate the string, and pull it out of recvq + recvq = recvq.substr(qpos); - catch (...) - { - ServerInstance->Logs->Log("USERS", DEBUG,"Exception in User::GetBuffer()"); - return ""; + // TODO should this be moved to when it was inserted in recvq? + ServerInstance->stats->statsRecv += qpos; + this->bytes_in += qpos; + this->cmds_in++; + + ServerInstance->Parser->ProcessBuffer(line, this); } } void User::AddWriteBuf(const std::string &data) { - if (!this->quitting && this->MyClass && !this->HasPrivPermission("users/flood/increased-buffers") && sendq.length() + data.length() > this->MyClass->GetSendqMax()) + // Don't bother sending text to remote users! + if (IS_REMOTE(this)) + return; + if (!quitting && MyClass && getSendQSize() + data.length() > MyClass->GetSendqMax() && !HasPrivPermission("users/flood/increased-buffers")) { /* * Fix by brain - Set the error text BEFORE calling, because @@ -664,66 +573,36 @@ void User::AddWriteBuf(const std::string &data) * to repeatedly add the text to the sendq! */ ServerInstance->Users->QuitUser(this, "SendQ exceeded"); - ServerInstance->SNO->WriteToSnoMask('a', "User %s SendQ of %lu exceeds connect class maximum of %lu",this->nick.c_str(),(unsigned long int)sendq.length() + data.length(),this->MyClass->GetSendqMax()); + ServerInstance->SNO->WriteToSnoMask('a', "User %s SendQ of %lu exceeds connect class maximum of %lu", + nick.c_str(), (unsigned long)getSendQSize() + data.length(), MyClass->GetSendqMax()); return; } // We still want to append data to the sendq of a quitting user, // e.g. their ERROR message that says 'closing link' - if (data.length() > MAXBUF - 2) /* MAXBUF has a value of 514, to account for line terminators */ - sendq.append(data.substr(0,MAXBUF - 4)).append("\r\n"); /* MAXBUF-4 = 510 */ - else - sendq.append(data); + WriteData(data); } -// send AS MUCH OF THE USERS SENDQ as we are able to (might not be all of it) -void User::FlushWriteBuf() +void User::OnError(BufferedSocketError) { - if (this->fd == FD_MAGIC_NUMBER) - { - sendq.clear(); - return; - } + ServerInstance->Users->QuitUser(this, getError()); +} - if ((sendq.length()) && (this->fd != FD_MAGIC_NUMBER)) +void User::cull() +{ + if (!quitting) + ServerInstance->Users->QuitUser(this, "Culled without QuitUser"); + if (IS_LOCAL(this)) { - int old_sendq_length = sendq.length(); - int n_sent = ServerInstance->SE->Send(this, this->sendq.data(), this->sendq.length(), 0); + if (fd != INT_MAX) + Close(); - if (n_sent == -1) - { - if (errno == EAGAIN) - { - /* The socket buffer is full. This isnt fatal, - * try again later. - */ - ServerInstance->SE->WantWrite(this); - } - else - { - /* Fatal error, set write error and bail */ - ServerInstance->Users->QuitUser(this, errno ? strerror(errno) : "Write error"); - return; - } - } + std::vector<User*>::iterator x = find(ServerInstance->Users->local_users.begin(),ServerInstance->Users->local_users.end(),this); + if (x != ServerInstance->Users->local_users.end()) + ServerInstance->Users->local_users.erase(x); else - { - /* advance the queue */ - if (n_sent) - this->sendq = this->sendq.substr(n_sent); - /* update the user's stats counters */ - this->bytes_out += n_sent; - this->cmds_out++; - if (n_sent != old_sendq_length) - ServerInstance->SE->WantWrite(this); - } - } - - /* note: NOT else if! */ - if (this->sendq.empty()) - { - FOREACH_MOD(I_OnBufferFlushed,OnBufferFlushed(this)); + ServerInstance->Logs->Log("USERS", DEBUG, "Failed to remove user from vector"); } } @@ -1191,35 +1070,29 @@ bool User::SetClientIP(const char* sip) return irc::sockets::aptosa(sip, 0, &client_sa); } +static std::string wide_newline("\r\n"); + void User::Write(const std::string& text) { if (!ServerInstance->SE->BoundsCheckFd(this)) return; - ServerInstance->Logs->Log("USEROUTPUT", DEBUG,"C[%d] O %s", this->GetFd(), text.c_str()); - - if (this->GetIOHook()) + if (text.length() > MAXBUF - 2) { - /* XXX: The lack of buffering here is NOT a bug, modules implementing this interface have to - * implement their own buffering mechanisms - */ - try - { - this->GetIOHook()->OnRawSocketWrite(this->fd, text.data(), text.length()); - this->GetIOHook()->OnRawSocketWrite(this->fd, "\r\n", 2); - } - catch (CoreException& modexcept) - { - ServerInstance->Logs->Log("USEROUTPUT", DEBUG, "%s threw an exception: %s", modexcept.GetSource(), modexcept.GetReason()); - } - } - else - { - this->AddWriteBuf(text); - this->AddWriteBuf("\r\n"); + // this should happen rarely or never. Crop the string at 512 and try again. + std::string try_again = text.substr(0, MAXBUF - 2); + Write(try_again); + return; } + + ServerInstance->Logs->Log("USEROUTPUT", DEBUG,"C[%d] O %s", this->GetFd(), text.c_str()); + + this->AddWriteBuf(text); + this->AddWriteBuf(wide_newline); + ServerInstance->stats->statsSent += text.length() + 2; - ServerInstance->SE->WantWrite(this); + this->bytes_out += text.length() + 2; + this->cmds_out++; } /** Write() @@ -1904,25 +1777,6 @@ void User::ShowRULES() this->WriteNumeric(RPL_RULESEND, "%s :End of RULES command.",this->nick.c_str()); } -void User::HandleEvent(EventType et, int errornum) -{ - if (this->quitting) // drop everything, user is due to be quit - return; - - switch (et) - { - case EVENT_READ: - ServerInstance->ProcessUser(this); - break; - case EVENT_WRITE: - this->FlushWriteBuf(); - break; - case EVENT_ERROR: - ServerInstance->Users->QuitUser(this, errornum ? strerror(errornum) : "Client closed the connection"); - break; - } -} - void User::IncreasePenalty(int increase) { this->Penalty += increase; |