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;
}
Example #4
0
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;
}
Example #5
0
static void WrapBindPort(int portIdx, int periId)
{
	if (periId >= 0 && periId < s_periMapSize) {
		BindPort(portIdx, s_periMap[periId]);
	}
}