示例#1
0
IpPort getIpPortFromSockAddr(const SockAddr &sa){
	const int family = sa.getFamily();
	if(family == AF_INET){
		if(sa.getSize() < sizeof(::sockaddr_in)){
			LOG_POSEIDON_WARNING("Invalid IPv4 SockAddr: size = ", sa.getSize());
			DEBUG_THROW(Exception, sslit("Invalid IPv4 SockAddr"));
		}
		char ip[INET_ADDRSTRLEN];
		const char *const str = ::inet_ntop(AF_INET,
			&static_cast<const ::sockaddr_in *>(sa.getData())->sin_addr, ip, sizeof(ip));
		if(!str){
			DEBUG_THROW(SystemException);
		}
		return IpPort(SharedNts(str),
			loadBe(static_cast<const ::sockaddr_in *>(sa.getData())->sin_port));
	} else if(family == AF_INET6){
		if(sa.getSize() < sizeof(::sockaddr_in6)){
			LOG_POSEIDON_WARNING("Invalid IPv6 SockAddr: size = ", sa.getSize());
			DEBUG_THROW(Exception, sslit("Invalid IPv6 SockAddr"));
		}
		char ip[INET6_ADDRSTRLEN];
		const char *const str = ::inet_ntop(AF_INET6,
			&static_cast<const ::sockaddr_in6 *>(sa.getData())->sin6_addr, ip, sizeof(ip));
		if(!str){
			DEBUG_THROW(SystemException);
		}
		return IpPort(SharedNts(str),
			loadBe(static_cast<const ::sockaddr_in6 *>(sa.getData())->sin6_port));
	}

	LOG_POSEIDON_WARNING("Unknown IP protocol ", family);
	DEBUG_THROW(Exception, sslit("Unknown IP protocol"));
}
示例#2
0
boost::shared_ptr<const JobPromise> DnsDaemon::enqueue_for_looking_up(boost::shared_ptr<SockAddr> sock_addr, std::string host, unsigned port){
	PROFILE_ME;

	AUTO(promise, boost::make_shared<JobPromise>());

	const AUTO(param, new DnsCallbackParam(STD_MOVE(sock_addr), host, port, promise));
	atomic_add(g_pending_callback_count, 1, ATOMIC_RELAXED); // noexcept
	try {
		::sigevent sev;
		sev.sigev_notify            = SIGEV_THREAD;
		sev.sigev_value.sival_ptr   = param;
		sev.sigev_notify_function   = &dns_callback;
		sev.sigev_notify_attributes = NULLPTR;
		AUTO(pcb, &(param->cb));
		const int gai_code = ::getaddrinfo_a(GAI_NOWAIT, &pcb, 1, &sev); // noexcept
		if(gai_code != 0){
			LOG_POSEIDON_WARNING("DNS failure: gai_code = ", gai_code, ", err_msg = ", ::gai_strerror(gai_code));
			DEBUG_THROW(Exception, sslit("DNS failure"));
		}
	} catch(...){
		atomic_sub(g_pending_callback_count, 1, ATOMIC_RELAXED); // noexcept
		delete param;
		throw;
	}

	return promise;
}
示例#3
0
bool SockAddr::isPrivate() const {
	const int family = getFamily();
	if(family == AF_INET){
		const AUTO_REF(ip, reinterpret_cast<const unsigned char (&)[4]>(
			static_cast<const ::sockaddr_in *>(getData())->sin_addr));
		if(ip[0] == 0){ // 0.0.0.0/8: 当前网络地址
			return true;
		} else if(ip[0] == 10){ // 10.0.0.0/8: A 类私有地址
			return true;
		} else if(ip[0] == 127){ // 127.0.0.0/8: 回环地址
			return true;
		} else if((ip[0] == 172) && ((ip[1] & 0xF0) == 16)){ // 172.16.0.0/12: B 类私有地址
			return true;
		} else if((ip[0] == 169) && (ip[1] == 254)){ // 169.254.0.0/16: 链路本地地址
			return true;
		} else if((ip[0] == 192) && (ip[1] == 168)){ // 192.168.0.0/16: C 类私有地址
			return true;
		} else if(ip[0] >= 224){ // D 类、E 类地址和广播地址
			return true;
		}
		return false;
	} else if(family == AF_INET6){
		static const unsigned char ZEROES[16] = { };

		const AUTO_REF(ip, reinterpret_cast<const unsigned char (&)[16]>(
			static_cast<const ::sockaddr_in6 *>(getData())->sin6_addr));
		if(std::memcmp(ip, ZEROES, 15) == 0){
			if(ip[15] == 0){ // ::/128: 未指定的地址
				return true;
			}
			if(ip[15] == 1){ // ::1/128: 回环地址
				return true;
			}
		} else if((std::memcmp(ip, ZEROES, 10) == 0) && (ip[10] == 0xFF) && (ip[11] == 0xFF)){ // IPv4 翻译地址
			if(ip[12] == 0){ // 0.0.0.0/8: 当前网络地址
				return true;
			} else if(ip[12] == 10){ // 10.0.0.0/8: A 类私有地址
				return true;
			} else if(ip[12] == 127){ // 127.0.0.0/8: 回环地址
				return true;
			} else if((ip[12] == 172) && ((ip[13] & 0xF0) == 16)){ // 172.16.0.0/12: B 类私有地址
				return true;
			} else if((ip[12] == 169) && (ip[13] == 254)){ // 169.254.0.0/16: 链路本地地址
				return true;
			} else if((ip[12] == 192) && (ip[13] == 168)){ // 192.168.0.0/16: C 类私有地址
				return true;
			} else if(ip[12] >= 224){ // D 类、E 类地址和广播地址
				return true;
			}
		} else if((ip[0] == 0x01) && (std::memcmp(ip + 1, ZEROES, 7) == 0)){ // 100::/64 黑洞地址
			return true;
		} else if(ip[0] >= 0xFC){ // 私有地址、链路本地地址和广播地址
			return true;
		}
		return false;
	}

	LOG_POSEIDON_WARNING("Unknown IP protocol ", family);
	DEBUG_THROW(Exception, sslit("Unknown IP protocol"));
}
示例#4
0
const std::string &CsvParser::getRaw(const char *key) const {
	const AUTO_REF(map, m_data.at(m_row));
	const AUTO(it, map.find(key));
	if(it == map.end()){
		LOG_POSEIDON_WARNING("Column not found: ", key);
		return EMPTY_STRING;
	}
	return it->second;
}
示例#5
0
bool SockAddr::isIpv6() const {
	const int family = getFamily();
	if(family == AF_INET){
		return false;
	} else if(family == AF_INET6){
		return true;
	}

	LOG_POSEIDON_WARNING("Unknown IP protocol ", family);
	DEBUG_THROW(Exception, sslit("Unknown IP protocol"));
}
示例#6
0
bool isValidUtf8String(const std::string &str){
	PROFILE_ME;

	boost::uint32_t codePoint;
	for(AUTO(it, str.begin()); it != str.end(); ++it){
		codePoint = static_cast<unsigned char>(*it);
		if((codePoint & 0x80) == 0){
			continue;
		}
		const AUTO(bytes, (unsigned)__builtin_clz((~codePoint | 1) & 0xFF) - (sizeof(unsigned) - 1) * CHAR_BIT);
		if(bytes - 2 > 2){ // 2, 3, 4
			LOG_POSEIDON_WARNING("Invalid UTF-8 leading byte: bytes = ", bytes);
			return false;
		}
		codePoint &= (0xFFu >> bytes);
		for(unsigned i = 1; i < bytes; ++i){
			++it;
			if(it == str.end()){
				LOG_POSEIDON_WARNING("String is truncated.");
				return false;
			}
			const unsigned trailing = static_cast<unsigned char>(*it);
			if((trailing & 0xC0u) != 0x80u){
				LOG_POSEIDON_WARNING("Invalid UTF-8 trailing byte: trailing = 0x",
					std::hex, std::setw(2), std::setfill('0'), trailing);
				return false;
			}
		}
		if(codePoint > 0x10FFFFu){
			LOG_POSEIDON_WARNING("Invalid UTF-8 code point: codePoint = 0x",
				std::hex, std::setw(6), std::setfill('0'), codePoint);
			return false;
		}
		if(codePoint - 0xD800u < 0x800u){
			LOG_POSEIDON_WARNING("UTF-8 code point is reserved for UTF-16: codePoint = 0x",
				std::hex, std::setw(4), std::setfill('0'), codePoint);
			return false;
		}
	}
	return true;
}
示例#7
0
bool TcpServerBase::poll() const {
	UniqueFile client(::accept(get_fd(), NULLPTR, NULLPTR));
	if(!client){
		if(errno != EAGAIN){
			DEBUG_THROW(SystemException);
		}
		return false;
	}
	AUTO(session, on_client_connect(STD_MOVE(client)));
	if(!session){
		LOG_POSEIDON_WARNING("on_client_connect() returns a null pointer.");
		DEBUG_THROW(Exception, sslit("Null client pointer"));
	}
	if(m_ssl_factory){
		AUTO(ssl, m_ssl_factory->create_ssl());
		boost::scoped_ptr<SslFilterBase> filter(new SslFilter(STD_MOVE(ssl), session->get_fd()));
		session->init_ssl(STD_MOVE(filter));
	}
	session->set_timeout(EpollDaemon::get_tcp_request_timeout());
	EpollDaemon::add_session(session);
	LOG_POSEIDON_INFO("Accepted TCP connection from ", session->get_remote_info());
	return true;
}