bool SocketAddress::setIntern(Exception& ex,const string& host, UInt16 port,bool resolveHost) {
	IPAddress ip;
	Exception ignore;
	if (ip.set(ignore, host)) {
		set(ip, port);
		return true;
	}
	HostEntry entry;
	if (!resolveHost) {
		if (ignore)
			ex.set(ignore);
		return false;
	}
	if (!DNS::HostByName(ex, host, entry))
		return false;
	auto& addresses = entry.addresses();
	if (addresses.size() > 0) {
		// if we get both IPv4 and IPv6 addresses, prefer IPv4
		for (const IPAddress& address : addresses) {
			if (address.family() == IPAddress::IPv4) {
				set(address, port);
				return true;
			}
		}
		set(addresses.front(), port);
		return true;
	}
	ex.set(Exception::NETADDRESS, "No address found for the host ", host);
	return false;
}
Exemple #2
0
void SocketAddress::init(const std::string& host, Poco::UInt16 port)
{
	IPAddress ip;
	if (IPAddress::tryParse(host, ip))
	{
		init(ip, port);
#if defined(POCO_HAVE_IPv6)
		std::string::size_type pos = host.rfind('%');
		if (std::string::npos != pos)
		{
			std::string scope(host, pos + 1);
		#ifdef _WIN32
			((sockaddr_in6*)addr())->sin6_scope_id = atoi(scope.c_str());
		#else
			if (']' == scope[scope.length() - 1])
			{
				scope.resize(scope.length() - 1);
			}
			((sockaddr_in6*)addr())->sin6_scope_id = if_nametoindex(scope.c_str());
		#endif
		}
#endif
	}
	else
	{
		HostEntry he = DNS::hostByName(host);
		if (he.addresses().size() > 0)
			init(he.addresses()[0], port);
		else throw HostNotFoundException("No address found for host", host);
	}
}
Exemple #3
0
ADD_TEST(DNSTest, HostByName) {
	Exception ex;
	HostEntry hostEntry;

	DNS::HostByName(ex, "aliastest.appinf.com", hostEntry);
	CHECK(!ex)
	// different systems report different canonical names, unfortunately.
	CHECK(hostEntry.name() == "dnstest.appinf.com" || hostEntry.name() == "aliastest.appinf.com");

	CHECK(hostEntry.addresses().size() >= 1);
	CHECK(hostEntry.addresses().front().toString() == "1.2.3.4");

	DNS::HostByName(ex, "nohost.appinf.com", hostEntry);
	CHECK(ex); // must not to find the host
}
Exemple #4
0
ADD_TEST(DNSTest, HostByAddress) {
	Exception ex;
	HostEntry hostEntry;

	IPAddress ip;
	ip.set(ex, "80.122.195.86");
	CHECK(!ex)
	DNS::HostByAddress(ex, ip, hostEntry);
	CHECK(!ex)
	CHECK(hostEntry.name() == "mailhost.appinf.com");
	CHECK(hostEntry.aliases().empty());
	CHECK(hostEntry.addresses().size() >= 1);
	CHECK(hostEntry.addresses().front().toString() == "80.122.195.86");

	ip.set(ex, "10.0.244.253");
	CHECK(!ex)
	DNS::HostByAddress(ex, ip, hostEntry);
	CHECK(ex)
}
void SocketAddress::init(const std::string& host, Poco::UInt16 port)
{
	IPAddress ip;
	if (IPAddress::tryParse(host, ip))
	{
		init(ip, port);
	}
	else
	{
		HostEntry he = DNS::hostByName(host);
		HostEntry::AddressList addresses = he.addresses();
		if (addresses.size() > 0)
		{
#if defined(POCO_HAVE_IPv6)
			// if we get both IPv4 and IPv6 addresses, prefer IPv4
			std::sort(addresses.begin(), addresses.end(), AFLT());
#endif
			init(addresses[0], port);
		}
		else throw HostNotFoundException("No address found for host", host);
	}
}
Exemple #6
0
bool DNS::HostByName(Exception& ex, const char* hostname, HostEntry& host) {
	if (!Net::InitializeNetwork(ex))
		return false;

	struct addrinfo* pAI;
	struct addrinfo hints;
	memset(&hints, 0, sizeof(hints));
	hints.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
	int rc = getaddrinfo(hostname, NULL, &hints, &pAI); 
	if (rc == 0) {
		host.set(ex,pAI);
		freeaddrinfo(pAI);
		return true;
	}
	SetAIError(ex,rc, " (hostname=",hostname,")");
	return false;
}
Exemple #7
0
// BEWARE blocking method!!
bool DNS::HostByAddress(Exception& ex,const IPAddress& address, HostEntry& host) {
	if (!Net::InitializeNetwork(ex))
		return false;
	SocketAddress sa;
	sa.set(address, 0);
	static char fqname[1024];
	int rc = getnameinfo(sa.addr(), sa.size(), fqname, sizeof(fqname), NULL, 0, NI_NAMEREQD);
	if (rc == 0) {
		struct addrinfo* pAI;
		struct addrinfo hints;
		memset(&hints, 0, sizeof(hints));
		hints.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
		rc = getaddrinfo(fqname, NULL, &hints, &pAI);
		if (rc == 0) {
			host.set(ex, pAI);
			freeaddrinfo(pAI);
			return true;
		}
	}
	SetAIError(ex, rc, " (address=",address.toString(),")");
	return false;
}
Exemple #8
0
	void MulticastPoint::handle_timeout(const boost::system::error_code& error)
	{
		if (!error)
		{
			//std::cout<<"timeout"<<std::endl;
			canWarn = true; //Re enable send error warnings
			KSystem::Time::TimeAbsolute now = KSystem::Time::SystemTime::now();
			{
				//Clean old hosts first
				std::map<hostid, hostDescription>::iterator  t, hit = otherHosts.begin();
				KSystem::Time::TimeAbsolute oldest = now - KSystem::Time::TimeAbsolute::milliseconds(cleanupandbeacon * 4);

				while(hit != otherHosts.end())
				{
					if((*hit).first == Messaging::MessageEntry::HOST_ID_ANY_HOST) //Do not cleanup ANYHOST
					{
						++hit;
						continue;
					}

					if((*hit).second.lastseen < oldest)
					{
						//std::cout<<"Cleaning Host:"<<(*hit).first<<std::endl;
						t = hit++;
						otherHosts.erase(t);
					}
					else
						hit++;
				}

				cleanupLocalSubscriptions();


			}
			{
				HostSubscriptions *hs = HostSubscriptions::default_instance().New();
				hs->set_hostname(boost::asio::ip::host_name());
				std::map<hostid, hostDescription>::const_iterator hit = otherHosts.begin();

				for(; hit != otherHosts.end(); ++hit)
				{
					std::set<size_t>::const_iterator tit = (*hit).second.providesTopics.begin();

					for(; tit != (*hit).second.providesTopics.end(); ++tit)
					{
						Subscription *s = hs->add_topics();
						s->set_host((*hit).first);
						s->set_topicid(*tit);
						//std::cout<<"Requesting"<<(*hit).first<<" "<<(*tit)<<std::endl;
					}
				}

				Messaging::MessageEntry m;
				m.msg.reset(hs);
				m.topic = Messaging::Topics::Instance().getId("communication");
				m.msgclass = Messaging::MessageEntry::STATE;
				m.timestamp = now.wrapTo<KSystem::Time::TimeStamp>();
				m.host = Messaging::MessageEntry::HOST_ID_LOCAL_HOST;
				//std::cout<<"Beacon"<<std::endl;
				processOutGoing(m);
			}
			{
				//Internal message, forwarded to localhost, keeps track of known hosts, and this host info.
				KnownHosts *kn = KnownHosts::default_instance().New();
				//Who am I?
				kn->mutable_localhost()->set_hostid(thishost);
				kn->mutable_localhost()->set_hostname(boost::asio::ip::host_name());

				std::map<hostid, hostDescription>::const_iterator kit = otherHosts.begin();

				for(; kit != otherHosts.end(); ++kit)
				{
					if((*kit).first == Messaging::MessageEntry::HOST_ID_ANY_HOST) //Do not report ANYHOST
						continue;

					HostEntry *e = kn->add_entrylist();
					e->set_hostid((*kit).first);
					e->set_hostname((*kit).second.hostname);
				}

				Messaging::MessageEntry m;
				m.msg.reset(kn);
				m.topic = Messaging::Topics::Instance().getId("communication");
				m.msgclass = Messaging::MessageEntry::STATE;
				m.timestamp = now.wrapTo<KSystem::Time::TimeStamp>();
				m.host = Messaging::MessageEntry::HOST_ID_LOCAL_HOST;
				publish(m);
			}
			dep.cleanOlderThan(KSystem::Time::TimeAbsolute::milliseconds(cleanupandbeacon * 2));
			timer_.expires_from_now(boost::posix_time::milliseconds(cleanupandbeacon));
			timer_.async_wait(
			    boost::bind(&MulticastPoint::handle_timeout, this,
			                boost::asio::placeholders::error));
		}
	}
Exemple #9
0
	void MulticastPoint::handle_timeout(const boost::system::error_code& error)
	{
		if (!error)
		{
			//std::cout<<"timeout"<<std::endl;
			canWarn = true; //Re enable send error warnings
			boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
			{
				//Clean old hosts first
				std::map<hostid, hostDescription>::iterator  t, hit = otherHosts.begin();
				boost::posix_time::ptime oldest = now - boost::posix_time::milliseconds(cleanupandbeacon * 4);

				while(hit != otherHosts.end())
				{
					if((*hit).first == msgentry::HOST_ID_ANY_HOST) //Do not cleanup ANYHOST
					{
						++hit;
						continue;
					}

					if((*hit).second.lastseen < oldest)
					{
						//std::cout<<"Cleaning Host:"<<(*hit).first<<std::endl;
						t = hit++;
						otherHosts.erase(t);
					}
					else
						hit++;
				}

				std::set<size_t>  remSub;
				std::set<size_t>::iterator sit;
				//Iterate all needed topics
				remSub = localsubscriptions;

				for( hit = otherHosts.begin(); hit != otherHosts.end(); hit++)
					for(sit = (*hit).second.needsTopics.begin(); sit != (*hit).second.needsTopics.end(); ++sit)
						remSub.erase(*sit);

				for(sit = remSub.begin(); sit != remSub.end(); ++sit)
					localsubscriptions.erase(*sit);

				std::vector<msgentry> newsubscriptions;
				msgentry kh;
				kh.msgclass = msgentry::UNSUBSCRIBE_ON_TOPIC;
				kh.host = msgentry::HOST_ID_LOCAL_HOST;

				for(sit = remSub.begin(); sit != remSub.end(); ++sit)
				{
					kh.topic = (*sit);
					newsubscriptions.push_back(kh);
					//std::cout<<"Unsubscribe from:"<<(*sit)<<std::endl;
				}

				publish(newsubscriptions);
			}
			{
				HostSubscriptions *hs = HostSubscriptions::default_instance().New();
				hs->set_hostname(boost::asio::ip::host_name());
				std::map<hostid, hostDescription>::const_iterator hit = otherHosts.begin();

				for(; hit != otherHosts.end(); ++hit)
				{
					std::set<size_t>::const_iterator tit = (*hit).second.providesTopics.begin();

					for(; tit != (*hit).second.providesTopics.end(); ++tit)
					{
						Subscription *s = hs->add_topics();
						s->set_host((*hit).first);
						s->set_topicid(*tit);
						//std::cout<<"Requesting"<<(*hit).first<<" "<<(*tit)<<std::endl;
					}
				}

				msgentry m;
				m.msg.reset(hs);
				m.topic = Topics::Instance().getId("communication");
				m.msgclass = msgentry::STATE;
				m.timestamp = now;
				m.host = msgentry::HOST_ID_LOCAL_HOST;
				//std::cout<<"Beacon"<<std::endl;
				processOutGoing(m);
			}
			{
				//Internal message, forwarded to localhost, keeps track of known hosts, and this host info.
				KnownHosts *kn = KnownHosts::default_instance().New();
				//Who am I?
				kn->mutable_localhost()->set_hostid(thishost);
				kn->mutable_localhost()->set_hostname(boost::asio::ip::host_name());

				std::map<hostid, hostDescription>::const_iterator kit = otherHosts.begin();

				for(; kit != otherHosts.end(); ++kit)
				{
					if((*kit).first == msgentry::HOST_ID_ANY_HOST) //Do not report ANYHOST
						continue;

					HostEntry *e = kn->add_entrylist();
					e->set_hostid((*kit).first);
					e->set_hostname((*kit).second.hostname);
				}

				msgentry m;
				m.msg.reset(kn);
				m.topic = Topics::Instance().getId("communication");
				m.msgclass = msgentry::STATE;
				m.timestamp = now;
				m.host = msgentry::HOST_ID_LOCAL_HOST;
				publish(m);
			}
			dep.cleanOlderThan(boost::posix_time::milliseconds(cleanupandbeacon * 2));
			timer_.expires_from_now(boost::posix_time::milliseconds(cleanupandbeacon));
			timer_.async_wait(
			    boost::bind(&MulticastPoint::handle_timeout, this,
			                boost::asio::placeholders::error));
		}
	}