diff options
-rw-r--r-- | include/socket.h | 24 | ||||
-rw-r--r-- | src/configreader.cpp | 11 | ||||
-rw-r--r-- | src/inspircd.cpp | 42 | ||||
-rw-r--r-- | src/socket.cpp | 4 |
4 files changed, 56 insertions, 25 deletions
diff --git a/include/socket.h b/include/socket.h index 6ecb23020..36f020b25 100644 --- a/include/socket.h +++ b/include/socket.h @@ -136,10 +136,32 @@ namespace irc } } +/** Represents information about a failed port binding. */ +struct CoreExport FailedPort +{ + + /** The error which happened during binding. */ + int error; + + /** The endpoint on which we were attempting to bind. */ + irc::sockets::sockaddrs sa; + + /** The config tag that the listener was created from. */ + ConfigTag* tag; + + FailedPort(int err, irc::sockets::sockaddrs& ep, ConfigTag* cfg) + : error(err) + , sa(ep) + , tag(cfg) + { + } +}; + /** A list of failed port bindings, used for informational purposes on startup */ -typedef std::vector<std::pair<irc::sockets::sockaddrs, int> > FailedPortList; +typedef std::vector<FailedPort> FailedPortList; #include "socketengine.h" + /** This class handles incoming connections on client ports. * It will create a new User for every valid connection * and assign it a file descriptor. diff --git a/src/configreader.cpp b/src/configreader.cpp index 2a1da8fd8..0f2063a60 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -510,13 +510,12 @@ void ServerConfig::Apply(ServerConfig* old, const std::string &useruid) ServerInstance->BindPorts(pl); if (pl.size()) { - errstr << "Not all your client ports could be bound." << std::endl - << "The following port(s) failed to bind:" << std::endl; - - int j = 1; - for (FailedPortList::iterator i = pl.begin(); i != pl.end(); i++, j++) + std::cout << "Warning! Some of your listener" << (pl.size() == 1 ? "s" : "") << " failed to bind:" << std::endl; + for (FailedPortList::const_iterator iter = pl.begin(); iter != pl.end(); ++iter) { - errstr << j << ".\tAddress: " << i->first.str() << "\tReason: " << strerror(i->second) << std::endl; + const FailedPort& fp = *iter; + errstr << " " << fp.sa.str() << ": " << strerror(fp.error) << std::endl + << " " << "Created from <bind> tag at " << fp.tag->getTagLocation() << std::endl; } } } diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 384f783aa..2035960bd 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -358,6 +358,31 @@ namespace signal(SIGTERM, InspIRCd::SetSignal); } + void TryBindPorts() + { + FailedPortList pl; + ServerInstance->BindPorts(pl); + + if (!pl.empty()) + { + std::cout << con_red << "Warning!" << con_reset << " Some of your listener" << (pl.size() == 1 ? "s" : "") << " failed to bind:" << std::endl + << std::endl; + + for (FailedPortList::const_iterator iter = pl.begin(); iter != pl.end(); ++iter) + { + const FailedPort& fp = *iter; + std::cout << " " << con_bright << fp.sa.str() << con_reset << ": " << strerror(fp.error) << '.' << std::endl + << " " << "Created from <bind> tag at " << fp.tag->getTagLocation() << std::endl + << std::endl; + } + + std::cout << con_bright << "Hints:" << con_reset << std::endl + << "- For TCP/IP listeners try using a public IP address in <bind:address> instead" << std::endl + << " of * of leaving it blank." << std::endl + << "- For UNIX socket listeners try enabling <bind:rewrite> to replace old sockets." << std::endl; + } + } + // Required for returning the proper value of EXIT_SUCCESS for the parent process. void VoidSignalHandler(int) { @@ -529,9 +554,6 @@ InspIRCd::InspIRCd(int argc, char** argv) // This is needed as all new XLines are marked pending until ApplyLines() is called this->XLines->ApplyLines(); - FailedPortList pl; - size_t bounditems = BindPorts(pl); - std::cout << std::endl; this->Modules->LoadAll(); @@ -539,19 +561,7 @@ InspIRCd::InspIRCd(int argc, char** argv) // Build ISupport as ModuleManager::LoadAll() does not do it this->ISupport.Build(); - if (!pl.empty()) - { - std::cout << std::endl << "WARNING: Not all your client ports could be bound -- " << std::endl << "starting anyway with " << bounditems - << " of " << (bounditems + pl.size()) << " client ports bound." << std::endl << std::endl; - std::cout << "The following port(s) failed to bind:" << std::endl << std::endl; - int j = 1; - for (FailedPortList::iterator i = pl.begin(); i != pl.end(); i++, j++) - { - std::cout << j << ".\tAddress: " << i->first.str() << " \tReason: " << strerror(i->second) << std::endl; - } - - std::cout << std::endl << "Hint: Try using a public IP instead of blank or *" << std::endl; - } + TryBindPorts(); std::cout << "InspIRCd is now running as '" << Config->ServerName << "'[" << Config->GetSID() << "] with " << SocketEngine::GetMaxFds() << " max open sockets" << std::endl; diff --git a/src/socket.cpp b/src/socket.cpp index 736e09486..64dc7ef25 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -86,7 +86,7 @@ size_t InspIRCd::BindPorts(FailedPortList& failed_ports) continue; if (!BindPort(tag, bindspec, old_ports)) - failed_ports.push_back(std::make_pair(bindspec, errno)); + failed_ports.push_back(FailedPort(errno, bindspec, tag)); else bound++; } @@ -120,7 +120,7 @@ size_t InspIRCd::BindPorts(FailedPortList& failed_ports) irc::sockets::untosa(fullpath, bindspec); if (!BindPort(tag, bindspec, old_ports)) - failed_ports.push_back(std::make_pair(bindspec, errno)); + failed_ports.push_back(FailedPort(errno, bindspec, tag)); else bound++; } |