diff options
author | brain <brain@e03df62e-2008-0410-955e-edbf42e46eb7> | 2007-05-11 18:38:00 +0000 |
---|---|---|
committer | brain <brain@e03df62e-2008-0410-955e-edbf42e46eb7> | 2007-05-11 18:38:00 +0000 |
commit | bfcaef8623bb3f8faf1141eb7b3805ab75ae97dd (patch) | |
tree | f26d108a63a8d311c64b400e58d5d1b7eff39bec | |
parent | b469531385d6d65b2f9dface80fe1ab4b9e19e15 (diff) |
Refactor port binding, warning not yet tested fully
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@6982 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r-- | include/configreader.h | 13 | ||||
-rw-r--r-- | include/inspircd.h | 16 | ||||
-rw-r--r-- | include/modules.h | 2 | ||||
-rw-r--r-- | include/socket.h | 14 | ||||
-rw-r--r-- | src/cmd_stats.cpp | 11 | ||||
-rw-r--r-- | src/configreader.cpp | 4 | ||||
-rw-r--r-- | src/dns.cpp | 2 | ||||
-rw-r--r-- | src/inspircd.cpp | 57 | ||||
-rw-r--r-- | src/modules/extra/m_ssl_gnutls.cpp | 13 | ||||
-rw-r--r-- | src/modules/extra/m_ssl_openssl.cpp | 13 | ||||
-rw-r--r-- | src/modules/m_xmlsocket.cpp | 13 | ||||
-rw-r--r-- | src/socket.cpp | 121 |
12 files changed, 97 insertions, 182 deletions
diff --git a/include/configreader.h b/include/configreader.h index eefa359c9..db4c6d3d5 100644 --- a/include/configreader.h +++ b/include/configreader.h @@ -426,11 +426,6 @@ class ServerConfig : public Extensible */ char HideKillsServer[MAXBUF]; - /** A list of IP addresses the server is listening - * on. - */ - char addrs[MAXBUF][255]; - /** The MOTD file, cached in a file_cache type. */ file_cache MOTD; @@ -453,13 +448,9 @@ class ServerConfig : public Extensible */ std::vector<std::string> module_names; - /** A list of ports which the server is listening on - */ - int ports[255]; - - /** A list of the file descriptors for the listening client ports + /** A list of the classes for listening client ports */ - ListenSocket* openSockfd[255]; + std::vector<ListenSocket*> ports; /** Boolean sets of which modules implement which functions */ diff --git a/include/inspircd.h b/include/inspircd.h index d9918aa73..71a36f9b5 100644 --- a/include/inspircd.h +++ b/include/inspircd.h @@ -187,24 +187,17 @@ class serverstats : public classbase /** Total bytes of data received */ double statsRecv; - /** Number of bound listening ports - */ - unsigned long BoundPortCount; - /** Cpu usage at last sample */ timeval LastCPU; - /** Time last sample was read */ timeval LastSampled; - /** The constructor initializes all the counts to zero */ serverstats() : statsAccept(0), statsRefused(0), statsUnknown(0), statsCollisions(0), statsDns(0), - statsDnsGood(0), statsDnsBad(0), statsConnects(0), statsSent(0.0), statsRecv(0.0), - BoundPortCount(0) + statsDnsGood(0), statsDnsBad(0), statsConnects(0), statsSent(0.0), statsRecv(0.0) { } }; @@ -586,13 +579,6 @@ class InspIRCd : public classbase */ int BindPorts(bool bail, int &found_ports, FailedPortList &failed_ports); - /** Returns true if this server has the given port bound to the given address - * @param port The port number - * @param addr The address - * @return True if we have a port listening on this address - */ - bool HasPort(int port, char* addr); - /** Binds a socket on an already open file descriptor * @param sockfd A valid file descriptor of an open socket * @param port The port number to bind to diff --git a/include/modules.h b/include/modules.h index fe921a540..752479014 100644 --- a/include/modules.h +++ b/include/modules.h @@ -75,7 +75,7 @@ enum MessageType { * ipv4 servers, so this value will be ten times as * high on ipv6 servers. */ -#define NATIVE_API_VERSION 11022 +#define NATIVE_API_VERSION 11023 #ifdef IPV6 #define API_VERSION (NATIVE_API_VERSION * 10) #else diff --git a/include/socket.h b/include/socket.h index 4e7d89192..88478f2e3 100644 --- a/include/socket.h +++ b/include/socket.h @@ -152,10 +152,12 @@ class ListenSocket : public EventHandler InspIRCd* ServerInstance; std::string desc; int family; + std::string bind_addr; + int bind_port; public: /** Create a new listening socket */ - ListenSocket(InspIRCd* Instance, int sockfd, irc::sockets::insp_sockaddr client, irc::sockets::insp_sockaddr server, int port, char* addr); + ListenSocket(InspIRCd* Instance, int port, char* addr); /** Handle an I/O event */ void HandleEvent(EventType et, int errornum = 0); @@ -173,6 +175,16 @@ class ListenSocket : public EventHandler { return desc; } + + int GetPort() + { + return bind_port; + } + + std::string &GetIP() + { + return bind_addr; + } }; #endif diff --git a/src/cmd_stats.cpp b/src/cmd_stats.cpp index a23dc250e..7a232e033 100644 --- a/src/cmd_stats.cpp +++ b/src/cmd_stats.cpp @@ -66,13 +66,14 @@ void DoStats(InspIRCd* ServerInstance, char statschar, userrec* user, string_lis if (t->registered == REG_ALL) pc[t->GetPort()]++; } - for (unsigned int i = 0; i < ServerInstance->stats->BoundPortCount; i++) + for (size_t i = 0; i < ServerInstance->Config->ports.size(); i++) { - if (pc[ServerInstance->Config->ports[i]] >= 0) + if (pc[ServerInstance->Config->ports[i]->GetPort()] >= 0) { - results.push_back(sn+" 249 "+user->nick+" :p:"+ConvToStr(ServerInstance->Config->ports[i])+" (" + ConvToStr(pc[ServerInstance->Config->ports[i]])+" client" + - (pc[ServerInstance->Config->ports[i]] != 1 ? "s" : "") + "), "+ServerInstance->Config->openSockfd[i]->GetDescription()); - pc[ServerInstance->Config->ports[i]] = -1; + results.push_back(sn+" 249 "+user->nick+" :p:"+ConvToStr(ServerInstance->Config->ports[i]->GetPort())+" (" + + ConvToStr(pc[ServerInstance->Config->ports[i]->GetPort()])+" client" + (pc[ServerInstance->Config->ports[i]->GetPort()] != 1 ? "s" : "") + "), "+ + ServerInstance->Config->ports[i]->GetDescription()); + pc[ServerInstance->Config->ports[i]->GetPort()] = -1; } } } diff --git a/src/configreader.cpp b/src/configreader.cpp index 0b3b806e3..1bc530b9b 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -846,12 +846,12 @@ void ServerConfig::Read(bool bail, userrec* user) { int found_ports = 0; FailedPortList pl; - ServerInstance->stats->BoundPortCount = ServerInstance->BindPorts(false, found_ports, pl); + ServerInstance->BindPorts(false, found_ports, pl); if (pl.size()) { user->WriteServ("NOTICE %s :*** Not all your client ports could be bound.", user->nick); - user->WriteServ("NOTICE %s :*** The following port%s failed to bind:", user->nick, found_ports - ServerInstance->stats->BoundPortCount != 1 ? "s" : ""); + user->WriteServ("NOTICE %s :*** The following port(s) failed to bind:", user->nick); int j = 1; for (FailedPortList::iterator i = pl.begin(); i != pl.end(); i++, j++) { diff --git a/src/dns.cpp b/src/dns.cpp index 33dba1abb..c04ab4cc1 100644 --- a/src/dns.cpp +++ b/src/dns.cpp @@ -1152,7 +1152,7 @@ unsigned long DNS::PRNG() gettimeofday(&n,NULL); val = (n.tv_usec ^ getpid() ^ geteuid() ^ (this->currid++)) ^ s->statsAccept + n.tv_sec; val = val + s->statsCollisions ^ s->statsDnsGood - s->statsDnsBad; - val += (s->statsConnects ^ (unsigned long)s->statsSent ^ (unsigned long)s->statsRecv) - s->BoundPortCount; + val += (s->statsConnects ^ (unsigned long)s->statsSent ^ (unsigned long)s->statsRecv) - ServerInstance->Config->ports.size(); return val; } diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 46e469d61..c78f44f46 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -78,13 +78,13 @@ void InspIRCd::Cleanup() std::vector<std::string> mymodnames; int MyModCount = this->GetModuleCount(); - for (unsigned int i = 0; i < stats->BoundPortCount; i++) + for (unsigned int i = 0; i < Config->ports.size(); i++) { /* This calls the constructor and closes the listening socket */ - delete Config->openSockfd[i]; - Config->openSockfd[i] = NULL; + delete Config->ports[i]; } - stats->BoundPortCount = 0; + + Config->ports.clear(); /* Close all client sockets, or the new process inherits them */ for (std::vector<userrec*>::const_iterator i = this->local_users.begin(); i != this->local_users.end(); i++) @@ -396,18 +396,6 @@ InspIRCd::InspIRCd(int argc, char** argv) sleep(20); } - this->Modes = new ModeParser(this); - this->AddServerName(Config->ServerName); - CheckDie(); - InitializeDisabledCommands(Config->DisabledCommands, this); - stats->BoundPortCount = BindPorts(true, found_ports, pl); - - for(int t = 0; t < 255; t++) - Config->global_implementation[t] = 0; - - memset(&Config->implement_lists,0,sizeof(Config->implement_lists)); - - printf("\n"); this->SetSignals(); if (!Config->nofork) @@ -420,30 +408,44 @@ InspIRCd::InspIRCd(int argc, char** argv) } } - /* Because of limitations in kqueue on freebsd, we must fork BEFORE we + + /* Because of limitations in kqueue on freebsd, we must fork BEFORE we * initialize the socket engine. */ SocketEngineFactory* SEF = new SocketEngineFactory(); SE = SEF->Create(this); delete SEF; + this->Modes = new ModeParser(this); + this->AddServerName(Config->ServerName); + CheckDie(); + InitializeDisabledCommands(Config->DisabledCommands, this); + int bounditems = BindPorts(true, found_ports, pl); + + for(int t = 0; t < 255; t++) + Config->global_implementation[t] = 0; + + memset(&Config->implement_lists,0,sizeof(Config->implement_lists)); + + printf("\n"); + this->Res = new DNS(this); this->LoadAllModules(); /* Just in case no modules were loaded - fix for bug #101 */ this->BuildISupport(); - if ((stats->BoundPortCount == 0) && (found_ports > 0)) + if ((Config->ports.size() == 0) && (found_ports > 0)) { printf("\nERROR: I couldn't bind any ports! Are you sure you didn't start InspIRCd twice?\n"); Log(DEFAULT,"ERROR: I couldn't bind any ports! Are you sure you didn't start InspIRCd twice?"); Exit(EXIT_STATUS_BIND); } - if (stats->BoundPortCount != (unsigned int)found_ports) + if (Config->ports.size() != (unsigned int)found_ports) { - printf("\nWARNING: Not all your client ports could be bound --\nstarting anyway with %ld of %d client ports bound.\n\n", stats->BoundPortCount, found_ports); - printf("The following port%s failed to bind:\n", found_ports - stats->BoundPortCount != 1 ? "s" : ""); + printf("\nWARNING: Not all your client ports could be bound --\nstarting anyway with %d of %d client ports bound.\n\n", bounditems, found_ports); + printf("The following port(s) failed to bind:\n"); int j = 1; for (FailedPortList::iterator i = pl.begin(); i != pl.end(); i++, j++) { @@ -451,19 +453,6 @@ InspIRCd::InspIRCd(int argc, char** argv) } } - /* Add the listening sockets used for client inbound connections - * to the socket engine - */ - for (unsigned long count = 0; count < stats->BoundPortCount; count++) - { - if (!SE->AddFd(Config->openSockfd[count])) - { - printf("\nEH? Could not add listener to socketengine. You screwed up, aborting.\n"); - Log(DEFAULT,"EH? Could not add listener to socketengine. You screwed up, aborting."); - Exit(EXIT_STATUS_INTERNAL); - } - } - if (!Config->nofork) { if (kill(getppid(), SIGTERM) == -1) diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index 0e923df41..5d95e75cf 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -140,9 +140,9 @@ class ModuleSSLGnuTLS : public Module if (ServerInstance->Config->AddIOHook(portno, this)) { listenports.push_back(portno); - for (unsigned int i = 0; i < ServerInstance->stats->BoundPortCount; i++) - if (ServerInstance->Config->ports[i] == portno) - ServerInstance->Config->openSockfd[i]->SetDescription("ssl"); + for (size_t i = 0; i < ServerInstance->Config->ports.size(); i++) + if (ServerInstance->Config->ports[i]->GetPort() == portno) + ServerInstance->Config->ports[i]->SetDescription("ssl"); ServerInstance->Log(DEFAULT, "m_ssl_gnutls.so: Enabling SSL for port %d", portno); } else @@ -264,10 +264,9 @@ class ModuleSSLGnuTLS : public Module for(unsigned int i = 0; i < listenports.size(); i++) { ServerInstance->Config->DelIOHook(listenports[i]); - for (unsigned int j = 0; j < ServerInstance->stats->BoundPortCount; j++) - if (ServerInstance->Config->ports[j] == listenports[i]) - if (ServerInstance->Config->openSockfd[j]) - ServerInstance->Config->openSockfd[j]->SetDescription("plaintext"); + for (size_t j = 0; j < ServerInstance->Config->ports.size(); j++) + if (ServerInstance->Config->ports[j]->GetPort() == listenports[i]) + ServerInstance->Config->ports[j]->SetDescription("plaintext"); } } } diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 53c595365..e073eba81 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -178,9 +178,9 @@ class ModuleSSLOpenSSL : public Module if (ServerInstance->Config->AddIOHook(portno, this)) { listenports.push_back(portno); - for (unsigned int i = 0; i < ServerInstance->stats->BoundPortCount; i++) - if (ServerInstance->Config->ports[i] == portno) - ServerInstance->Config->openSockfd[i]->SetDescription("ssl"); + for (size_t i = 0; i < ServerInstance->Config->ports.size(); i++) + if (ServerInstance->Config->ports[i]->GetPort() == portno) + ServerInstance->Config->ports[i]->SetDescription("ssl"); ServerInstance->Log(DEFAULT, "m_ssl_openssl.so: Enabling SSL for port %d", portno); } else @@ -314,10 +314,9 @@ class ModuleSSLOpenSSL : public Module for(unsigned int i = 0; i < listenports.size(); i++) { ServerInstance->Config->DelIOHook(listenports[i]); - for (unsigned int j = 0; j < ServerInstance->stats->BoundPortCount; j++) - if (ServerInstance->Config->ports[j] == listenports[i]) - if (ServerInstance->Config->openSockfd[j]) - ServerInstance->Config->openSockfd[j]->SetDescription("plaintext"); + for (size_t j = 0; j < ServerInstance->Config->ports.size(); j++) + if (ServerInstance->Config->ports[j]->GetPort() == listenports[i]) + ServerInstance->Config->ports[j]->SetDescription("plaintext"); } } } diff --git a/src/modules/m_xmlsocket.cpp b/src/modules/m_xmlsocket.cpp index 09ffe6ca9..1cf9fafa2 100644 --- a/src/modules/m_xmlsocket.cpp +++ b/src/modules/m_xmlsocket.cpp @@ -62,9 +62,9 @@ class ModuleXMLSocket : public Module if (ServerInstance->Config->AddIOHook(portno, this)) { listenports.push_back(portno); - for (unsigned int i = 0; i < ServerInstance->stats->BoundPortCount; i++) - if (ServerInstance->Config->ports[i] == portno) - ServerInstance->Config->openSockfd[i]->SetDescription("xml"); + for (size_t i = 0; i < ServerInstance->Config->ports.size(); i++) + if (ServerInstance->Config->ports[i]->GetPort() == portno) + ServerInstance->Config->ports[i]->SetDescription("xml"); } else { @@ -93,10 +93,9 @@ class ModuleXMLSocket : public Module for(unsigned int i = 0; i < listenports.size(); i++) { ServerInstance->Config->DelIOHook(listenports[i]); - for (unsigned int j = 0; j < ServerInstance->stats->BoundPortCount; j++) - if (ServerInstance->Config->ports[j] == listenports[i]) - if (ServerInstance->Config->openSockfd[j]) - ServerInstance->Config->openSockfd[j]->SetDescription("plaintext"); + for (size_t j = 0; j < ServerInstance->Config->ports.size(); j++) + if (ServerInstance->Config->ports[j]->GetPort() == listenports[i]) + ServerInstance->Config->ports[j]->SetDescription("plaintext"); } } } diff --git a/src/socket.cpp b/src/socket.cpp index 7a746ba0f..a828d1ece 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -36,19 +36,23 @@ const char inverted_bits[8] = { 0x00, /* 00000000 - 0 bits - never actually used }; -ListenSocket::ListenSocket(InspIRCd* Instance, int sockfd, insp_sockaddr client, insp_sockaddr server, int port, char* addr) : ServerInstance(Instance), desc("plaintext") +ListenSocket::ListenSocket(InspIRCd* Instance, int port, char* addr) : ServerInstance(Instance), desc("plaintext"), bind_addr(addr), bind_port(port) { - this->SetFd(sockfd); - if (!Instance->BindSocket(this->fd,port,addr)) - this->fd = -1; + this->SetFd(OpenTCPSocket(addr)); + if (this->GetFd() > -1) + { + if (!Instance->BindSocket(this->fd,port,addr)) + this->fd = -1; #ifdef IPV6 - if ((!*addr) || (strchr(addr,':'))) - this->family = AF_INET6; - else - this->family = AF_INET; + if ((!*addr) || (strchr(addr,':'))) + this->family = AF_INET6; + else + this->family = AF_INET; #else - this->family = AF_INET; + this->family = AF_INET; #endif + Instance->SE->AddFd(this); + } } ListenSocket::~ListenSocket() @@ -464,29 +468,10 @@ int irc::sockets::OpenTCPSocket(char* addr, int socktype) } /* XXX: Probably belongs in class InspIRCd */ -bool InspIRCd::HasPort(int port, char* addr) -{ - for (unsigned long count = 0; count < stats->BoundPortCount; count++) - { - if ((port == Config->ports[count]) && (!strcasecmp(Config->addrs[count],addr))) - { - return true; - } - } - return false; -} - -/* XXX: Probably belongs in class InspIRCd */ int InspIRCd::BindPorts(bool bail, int &ports_found, FailedPortList &failed_ports) { char configToken[MAXBUF], Addr[MAXBUF], Type[MAXBUF]; - insp_sockaddr client, server; - int clientportcount = 0; - int BoundPortCount = 0; - - ports_found = 0; - - int InitialPortCount = stats->BoundPortCount; + int bound = 0; for (int count = 0; count < Config->ConfValueEnum(Config->config_data, "bind"); count++) { @@ -497,80 +482,34 @@ int InspIRCd::BindPorts(bool bail, int &ports_found, FailedPortList &failed_port if ((!*Type) || (!strcmp(Type,"clients"))) { irc::portparser portrange(configToken, false); - long portno = -1; + int portno = -1; while ((portno = portrange.GetToken())) { - if (!HasPort(portno, Addr)) + if (*Addr == '*') + *Addr = 0; + + bool skip = false; + for (std::vector<ListenSocket*>::iterator n = Config->ports.begin(); n != Config->ports.end(); ++n) + if (((*n)->GetIP() == Addr) && ((*n)->GetPort() == portno)) + skip = true; + if (!skip) { - ports_found++; - Config->ports[clientportcount+InitialPortCount] = portno; - if (*Addr == '*') - *Addr = 0; - - strlcpy(Config->addrs[clientportcount+InitialPortCount],Addr,256); - clientportcount++; - } - } - } - - if (!bail) - { - int PortCount = clientportcount; - if (PortCount) - { - BoundPortCount = stats->BoundPortCount; - for (int count = InitialPortCount; count < InitialPortCount + PortCount; count++) - { - int fd = OpenTCPSocket(Config->addrs[count]); - if (fd == ERROR) + ListenSocket* ll = new ListenSocket(this, portno, Addr); + if (ll->GetFd() > -1) { - failed_ports.push_back(std::make_pair(Config->addrs[count],Config->ports[count])); + bound++; + Config->ports.push_back(ll); } else { - Config->openSockfd[BoundPortCount] = new ListenSocket(this,fd,client,server,Config->ports[count],Config->addrs[count]); - if (Config->openSockfd[BoundPortCount]->GetFd() > -1) - { - if (!SE->AddFd(Config->openSockfd[BoundPortCount])) - { - this->Log(DEFAULT,"ERK! Failed to add listening port to socket engine!"); - shutdown(Config->openSockfd[BoundPortCount]->GetFd(),2); - close(Config->openSockfd[BoundPortCount]->GetFd()); - delete Config->openSockfd[BoundPortCount]; - failed_ports.push_back(std::make_pair(Config->addrs[count],Config->ports[count])); - } - else - BoundPortCount++; - } + failed_ports.push_back(std::make_pair(Addr, portno)); } + ports_found++; } - return InitialPortCount + BoundPortCount; - } - return InitialPortCount; - } - } - - int PortCount = clientportcount; - - for (int count = 0; count < PortCount; count++) - { - int fd = OpenTCPSocket(Config->addrs[count]); - if (fd == ERROR) - { - failed_ports.push_back(std::make_pair(Config->addrs[count],Config->ports[count])); - } - else - { - Config->openSockfd[BoundPortCount] = new ListenSocket(this,fd,client,server,Config->ports[count],Config->addrs[count]); - if (Config->openSockfd[BoundPortCount]->GetFd() > -1) - { - BoundPortCount++; } - else - failed_ports.push_back(std::make_pair(Config->addrs[count],Config->ports[count])); } } - return BoundPortCount; + return bound; } const char* irc::sockets::insp_ntoa(insp_inaddr n) |