bool xRedisServerBase::Start(const char* ip, int port) { if (BindPort(ip, port)) { return Run(); } return false; }
bool SocketDescriptor::CreateTCPListener(unsigned port, unsigned backlog) { if (!CreateTCP()) return false; // Set socket options const int reuse = 1; #ifdef HAVE_POSIX const void *optval = &reuse; #else const char *optval = (const char *)&reuse; #endif setsockopt(Get(), SOL_SOCKET, SO_REUSEADDR, optval, sizeof(reuse)); // Bind socket to specified port number if (!BindPort(port)){ Close(); return false; } if (listen(Get(), backlog) < 0) { Close(); return false; } return true; }
bool SocketDescriptor::CreateUDPListener(unsigned port) { if (!CreateUDP()) return false; // Bind socket to specified port number if (!BindPort(port)){ Close(); return false; } return true; }
int InspIRCd::BindPorts(FailedPortList& failed_ports) { int bound = 0; std::vector<ListenSocket*> old_ports(ports.begin(), ports.end()); ConfigTagList tags = ServerInstance->Config->ConfTags("bind"); for (ConfigIter i = tags.first; i != tags.second; ++i) { ConfigTag* tag = i->second; // Are we creating a TCP/IP listener? const std::string address = tag->getString("address"); const std::string portlist = tag->getString("port"); if (!address.empty() || !portlist.empty()) { // InspIRCd supports IPv4 and IPv6 natively; no 4in6 required. if (strncasecmp(address.c_str(), "::ffff:", 7) == 0) this->Logs.Log("SOCKET", LOG_DEFAULT, "Using 4in6 (::ffff:) isn't recommended. You should bind IPv4 addresses directly instead."); // A TCP listener with no ports is not very useful. if (portlist.empty()) this->Logs.Log("SOCKET", LOG_DEFAULT, "TCP listener on %s at %s has no ports specified!", address.empty() ? "*" : address.c_str(), tag->getTagLocation().c_str()); irc::portparser portrange(portlist, false); for (int port; (port = portrange.GetToken()); ) { irc::sockets::sockaddrs bindspec; if (!irc::sockets::aptosa(address, port, bindspec)) continue; if (!BindPort(tag, bindspec, old_ports)) failed_ports.push_back(std::make_pair(bindspec, errno)); else bound++; } continue; } #ifndef _WIN32 // Are we creating a UNIX listener? const std::string path = tag->getString("path"); if (!path.empty()) { // UNIX socket paths are length limited to less than PATH_MAX. irc::sockets::sockaddrs bindspec; if (path.length() > std::min(ServerInstance->Config->Limits.MaxHost, sizeof(bindspec.un.sun_path))) { this->Logs.Log("SOCKET", LOG_DEFAULT, "UNIX listener on %s at %s specified a path that is too long!", path.c_str(), tag->getTagLocation().c_str()); continue; } // Create the bindspec manually (aptosa doesn't work with AF_UNIX yet). memset(&bindspec, 0, sizeof(bindspec)); bindspec.un.sun_family = AF_UNIX; memcpy(&bindspec.un.sun_path, path.c_str(), sizeof(bindspec.un.sun_path)); if (!BindPort(tag, bindspec, old_ports)) failed_ports.push_back(std::make_pair(bindspec, errno)); else bound++; } #endif } std::vector<ListenSocket*>::iterator n = ports.begin(); for (std::vector<ListenSocket*>::iterator o = old_ports.begin(); o != old_ports.end(); ++o) { while (n != ports.end() && *n != *o) n++; if (n == ports.end()) { this->Logs.Log("SOCKET", LOG_DEFAULT, "Port bindings slipped out of vector, aborting close!"); break; } this->Logs.Log("SOCKET", LOG_DEFAULT, "Port binding %s was removed from the config file, closing.", (**n).bind_sa.str().c_str()); delete *n; // this keeps the iterator valid, pointing to the next element n = ports.erase(n); } return bound; }
static void WrapBindPort(int portIdx, int periId) { if (periId >= 0 && periId < s_periMapSize) { BindPort(portIdx, s_periMap[periId]); } }