예제 #1
0
파일: socket.cpp 프로젝트: aszrul/inspircd
bool InspIRCd::BindPort(ConfigTag* tag, const irc::sockets::sockaddrs& sa, std::vector<ListenSocket*>& old_ports)
{
	for (std::vector<ListenSocket*>::iterator n = old_ports.begin(); n != old_ports.end(); ++n)
	{
		if ((**n).bind_sa == sa)
		{
			// Replace tag, we know addr and port match, but other info (type, ssl) may not.
			ServerInstance->Logs.Log("SOCKET", LOG_DEFAULT, "Replacing listener on %s from old tag at %s with new tag from %s",
				sa.str().c_str(), (*n)->bind_tag->getTagLocation().c_str(), tag->getTagLocation().c_str());
			(*n)->bind_tag = tag;
			(*n)->ResetIOHookProvider();

			old_ports.erase(n);
			return true;
		}
	}

	ListenSocket* ll = new ListenSocket(tag, sa);
	if (ll->GetFd() < 0)
	{
		ServerInstance->Logs.Log("SOCKET", LOG_DEFAULT, "Failed to listen on %s from tag at %s: %s",
			sa.str().c_str(), tag->getTagLocation().c_str(), strerror(errno));
		delete ll;
		return false;
	}

	ServerInstance->Logs.Log("SOCKET", LOG_DEFAULT, "Added a listener on %s from tag at %s", sa.str().c_str(), tag->getTagLocation().c_str());
	ports.push_back(ll);
	return true;
}
예제 #2
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;
		std::string porttag = tag->getString("port");
		std::string Addr = tag->getString("address");

		if (strncasecmp(Addr.c_str(), "::ffff:", 7) == 0)
			this->Logs->Log("SOCKET", LOG_DEFAULT, "Using 4in6 (::ffff:) isn't recommended. You should bind IPv4 addresses directly instead.");

		irc::portparser portrange(porttag, false);
		int portno = -1;
		while (0 != (portno = portrange.GetToken()))
		{
			irc::sockets::sockaddrs bindspec;
			if (!irc::sockets::aptosa(Addr, portno, bindspec))
				continue;
			std::string bind_readable = bindspec.str();

			bool skip = false;
			for (std::vector<ListenSocket*>::iterator n = old_ports.begin(); n != old_ports.end(); ++n)
			{
				if ((**n).bind_desc == bind_readable)
				{
					(*n)->bind_tag = tag; // Replace tag, we know addr and port match, but other info (type, ssl) may not
					(*n)->ResetIOHookProvider();

					skip = true;
					old_ports.erase(n);
					break;
				}
			}
			if (!skip)
			{
				ListenSocket* ll = new ListenSocket(tag, bindspec);

				if (ll->GetFd() > -1)
				{
					bound++;
					ports.push_back(ll);
				}
				else
				{
					failed_ports.push_back(std::make_pair(bind_readable, strerror(errno)));
					delete ll;
				}
			}
		}
	}

	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_desc.c_str());
		delete *n;

		// this keeps the iterator valid, pointing to the next element
		n = ports.erase(n);
	}

	return bound;
}