unsigned char parser::pop_byte_u() {
	if (! (m_data_now < m_data_end) ) _throw_error( format_error_read() );
	if (! ((m_data_end - m_data_now) >= 1) ) _throw_error( format_error_read() );
	assert( (m_data_now < m_data_end) && (m_data_now >= m_data_begin) );
	unsigned char c = *m_data_now;
	++m_data_now;
	return c;
}
void parser::skip_bytes_n(size_t size) {
	if (!size) return;
	if (! (m_data_now < m_data_end) ) _throw_error( format_error_read() ); // we run outside of string
	// casting below is ok, because std::ptrdiff_t is 64 bits signed value, and size_t is 64 bits unsigned value.
	// and we are sure that this ptrdiff > 0 because of earlier above condition
	if (! ( static_cast<size_t>(m_data_end - m_data_now) >= size) ) _throw_error( format_error_read() );
	assert( (m_data_now < m_data_end) && (m_data_now >= m_data_begin) );
	assert( (m_data_now + size <= m_data_end) );
	// auto from = m_data_now;
	m_data_now += size; // *** move
}
Exemple #3
0
c_haship_addr::c_haship_addr(tag_constr_by_addr_bin, const t_ipv6bin & data ) {
	if (! ( this->size() == data.size() ) ) {
		ostringstream oss; oss << "Trying to set hip address from binary data " << to_debug_b(data);
		_throw_error( std::runtime_error(oss.str()) );
	}
	for (size_t i=0; i<this->size(); ++i) this->at(i) = data.at(i);
}
Exemple #4
0
bool c_ip46_addr::operator== (const c_ip46_addr &rhs) const {
	if (this->m_tag == t_tag::tag_none) {
		_throw_error( std::invalid_argument("lhs: m_tag == tag_none") );
	}
	if (rhs.m_tag == t_tag::tag_none) {
		_throw_error( std::invalid_argument("rhs: m_tag == tag_none") );
	}
	if (this->m_tag != rhs.m_tag) {
		return false;
	}
	if (this->m_tag == t_tag::tag_ipv4) {
		return !memcmp(&this->m_ip_data.in4.sin_addr, &rhs.m_ip_data.in4.sin_addr, sizeof(in_addr));
	}
	else {
		return !memcmp(&this->m_ip_data.in6.sin6_addr, &rhs.m_ip_data.in6.sin6_addr, sizeof(in6_addr));
	}
}
Exemple #5
0
size_t c_tun_device_linux::read_from_tun(void *buf, size_t count) { // TODO throw if error
	_info("Reading from tuntap");
	ssize_t ret = read(m_tun_fd, buf, count); // <-- read data from TUN
	_info("Reading from tuntap - ret="<<ret);
	if (ret == -1) _throw_error( std::runtime_error("Read from tun error") );
	assert (ret >= 0);
	return static_cast<size_t>(ret);
}
Exemple #6
0
void c_the_program::init_library_sodium() {
	_fact(mo_file_reader::gettext("L_starting_lib_libsodium"));

	if (sodium_init() == -1) {
		_throw_error( std::runtime_error(mo_file_reader::gettext("L_lisodium_init_err")) );
	}
	_info(mo_file_reader::gettext("L_libsodium_ready"));
}
void parser::pop_bytes_n_into_buff(size_t size, char * buff) {
	if (! (m_data_now < m_data_end) ) _throw_error( format_error_read() ); // we run outside of string
	// casting below is ok, because std::ptrdiff_t is 64 bits signed value, and size_t is 64 bits unsigned value.
	// and we are sure that this ptrdiff > 0 because of earlier above condition
	if (! ( static_cast<size_t>(m_data_end - m_data_now) >= size) ) _throw_error( format_error_read() );
	assert(buff!=nullptr);

	assert( (m_data_now < m_data_end) && (m_data_now >= m_data_begin) );
	assert( (m_data_now + size <= m_data_end) );
	auto range1 = m_data_now;
	m_data_now += size; // *** move
	auto range2 = m_data_now;

	if ((range2 - range1) != size) {
		throw std::out_of_range("Variable overlap detected");
	}
	std::copy(range1, range2, buff); // copy the result into output
}
Exemple #8
0
bool c_ip46_addr::operator< (const c_ip46_addr &rhs) const {
	if (this->m_tag == t_tag::tag_none) {
		_throw_error( std::invalid_argument("lhs: m_tag == tag_none") );
	}
	if (rhs.m_tag == t_tag::tag_none) {
		_throw_error( std::invalid_argument("rhs: m_tag == tag_none") );
	}
	if (this->m_tag == t_tag::tag_ipv4 && rhs.m_tag == t_tag::tag_ipv6) {
		return true;
	}
	else if (this->m_tag == t_tag::tag_ipv6 && rhs.m_tag == t_tag::tag_ipv4) {
		return false;
	}

	int ret = 0;
    if (rhs.m_tag == t_tag::tag_ipv4) {
        ret = memcmp(&this->m_ip_data.in4.sin_addr, &rhs.m_ip_data.in4.sin_addr, sizeof(in_addr));
	}
    else {
        ret = memcmp(&this->m_ip_data.in6.sin6_addr, &rhs.m_ip_data.in6.sin6_addr, sizeof(in6_addr));
	}
	if (ret < 0) return true;
	else return false;
}
size_t c_udp_wrapper_linux::receive_data(void *data_buf, const size_t data_buf_size, c_ip46_addr &from_address) {
	sockaddr_in6 from_addr_raw; // peering address of peer (socket sender), raw format
	socklen_t from_addr_raw_size = sizeof(from_addr_raw); // ^ size of it
	auto size_read = recvfrom(m_socket, data_buf, data_buf_size, 0, reinterpret_cast<sockaddr*>( & from_addr_raw), & from_addr_raw_size);
	if (from_addr_raw_size == sizeof(sockaddr_in6)) { // the message arrive from IP pasted into sockaddr_in6 format
		_erro("NOT IMPLEMENTED yet - recognizing IP of ipv6 peer"); // peeripv6-TODO(r)(easy)
		// trivial
	}
	else if (from_addr_raw_size == sizeof(sockaddr_in)) { // the message arrive from IP pasted into sockaddr_in (ipv4) format
		sockaddr_in addr = * reinterpret_cast<sockaddr_in*>(& from_addr_raw); // mem-cast-TODO(p) confirm reinterpret
		from_address.set_ip4(addr);
	} else {
		_throw_error( std::runtime_error("Data arrived from unknown socket address type") );
	}
	return size_read;
}
Exemple #10
0
c_haship_addr::c_haship_addr(tag_constr_by_addr_dot, const t_ipv6dot & addr_string) {
	_dbg1("******************PARSING IP: addr_string " << addr_string);
	// use boost asio for parsing
	boost::asio::ip::address_v6 asio_addr_v6;
	try {
		asio_addr_v6 = boost::asio::ip::address_v6::from_string(addr_string);
		boost::asio::ip::address_v6::bytes_type asio_addr_bytes = asio_addr_v6.to_bytes();

		assert (asio_addr_bytes.size() == 16); // 16 = 128/8
		for (int i = 0; i < 128 / 8; ++i) {
			this->at(i) = asio_addr_bytes.at(i);
		}
	} catch (boost::exception &err) {
		_throw_error(std::invalid_argument("The IP address looks invalid ["+addr_string+"]"));
	}
	_dbg1("Parsed string addr :" << asio_addr_v6.to_string());
	_dbg1("Parsed bytes addr  :" << *this);
}
void test_shortstring_end(std::ostream &dbgout) {
	trivialserialize::generator gen(50);

	vector<string> test_varstring = {
		string("ABC"),
		string(""),
	};
	for (auto val : test_varstring) gen.push_varstring(val);

	const string input = gen.str();
	trivialserialize::parser parser( trivialserialize::parser::tag_caller_must_keep_this_string_valid() , input );

	for (auto val_expected : test_varstring) {
		auto val_given = parser.pop_varstring();
		dbgout<<"varstring decoded: [" << val_given << "] with size=" << val_given.size() << endl;
		bool ok = ( val_given == val_expected );
		if (!ok) _throw_error( std::runtime_error("Failed test for expected value " + (val_expected)) );
	}
}
Exemple #12
0
bool c_ip46_addr::is_ipv4(const string &ipstr) {
	as_zerofill< addrinfo > hint;
	struct addrinfo *result = nullptr;
	hint.ai_family = PF_UNSPEC;
	hint.ai_flags = AI_NUMERICHOST;
	int ret = getaddrinfo(ipstr.c_str(), nullptr, &hint, &result);
	if (ret) {
		_throw_error( std::invalid_argument("unknown address format") );
	}
	auto result_deleter = [&](struct addrinfo *result){freeaddrinfo(result);};
	std::unique_ptr<struct addrinfo, decltype(result_deleter)> result_ptr(result, result_deleter);
	if(result_ptr->ai_family == AF_INET) {
		return true;
	}
	else if (result_ptr->ai_family == AF_INET6) {
		return false;
	}
	_assert(false);
}
Exemple #13
0
void c_rpc_server::c_session::execute_rpc_command(const std::string &input_message) {
	try {
		nlohmann::json j = nlohmann::json::parse(input_message);
		const std::string cmd_name = j.begin().value();
		_dbg("cmd name " << cmd_name);
		// calling rpc function
		const std::string response = m_rpc_server_ptr->m_rpc_functions_map.at(cmd_name)(input_message);
		// serialize response
		assert(response.size() <= std::numeric_limits<uint16_t>::max());
		uint16_t size = static_cast<uint16_t>(response.size());
		m_write_data.resize(size + 2); ///< 2 first bytes for size
		m_write_data.at(0) = static_cast<char>(size >> 8);
		m_write_data.at(1) = static_cast<char>(size & 0xFF);
		for (size_t i = 0; i < response.size(); ++i)
			m_write_data.at(i + 2) = response.at(i);
		// send response

		_dbg("send packet");
		_dbg(m_write_data);
		std::array<unsigned char, crypto_auth_hmacsha512_BYTES> hash;
		int ret = crypto_auth_hmacsha512(hash.data(), reinterpret_cast<unsigned char *>(&m_write_data.at(2)), size, m_rpc_server_ptr->m_hmac_key.data());
		if (ret != 0) _throw_error(std::runtime_error("crypto_auth_hmacsha512 error"));
		_dbg("hmac");
		//for (const auto & byte : hash) std::cout << std::hex << "0x" << static_cast<int>(byte) << " ";
		//std::cout << std::dec << std::endl;
		std::array<boost::asio::const_buffer, 2> buffers = {
			{boost::asio::buffer(m_write_data.data(), m_write_data.size()),
			boost::asio::buffer(hash.data(), hash.size())}
		};
		m_socket.async_write_some(buffers,
			[this](const boost::system::error_code& error, std::size_t bytes_transferred) {
				write_handler(error, bytes_transferred);
		});
	}
	catch (const std::exception &e) {
		_erro( "exception in execute_rpc_command " << e.what() );
		_erro( "close connection\n" );
		delete_me();
		return;
	}
}
Exemple #14
0
void c_peering_udp::send_data_RAW_udp(const char * data, size_t data_size, int udp_socket) {
	_UNUSED(udp_socket);
	_info("UDP send to peer RAW. To IP: " << m_peering_addr <<
		", RAW-DATA: " << to_debug_b(std::string(data,data_size)) );

	//#ifdef __linux__
	switch (m_peering_addr.get_ip_type()) {
		case c_ip46_addr::t_tag::tag_ipv4 : {
			m_udp_wrapper.get().send_data(m_peering_addr, data, data_size);
		}
		break;
		case c_ip46_addr::t_tag::tag_ipv6 : {
			m_udp_wrapper.get().send_data(m_peering_addr, data, data_size);
		}
		break;
		default: {
			std::ostringstream oss; oss << m_peering_addr; // TODO
			_throw_error( std::runtime_error(string("Invalid IP type (when trying to send RAW udp): ") + oss.str()) );
		}
	}
	//#endif
}
Exemple #15
0
int c_tun_device_apple::get_tun_fd() const {
    if (m_tun_fd<0) _throw_error(std::runtime_error("Using not ready (m_tun_fd) tuntap device"));
    return m_tun_fd;
}
Exemple #16
0
int c_tun_device::get_tun_fd() const {
	_throw_error(std::runtime_error("Trying to get tun_fd of a basic generic tun device."));
}
Exemple #17
0
size_t c_tun_device_linux::write_to_tun(void *buf, size_t count) { // TODO throw if error
	auto ret = write(m_tun_fd, buf, count);
	if (ret == -1) _throw_error( std::runtime_error("Write to tun error") );
	assert (ret >= 0);
	return static_cast<size_t>(ret);
}
Exemple #18
0
void c_peering::send_data(const char * data, size_t data_size) {
	UNUSED(data); UNUSED(data_size);
	_throw_error( std::runtime_error("Used abstract send_data() that does nothing") );
}
Exemple #19
0
void c_peering_udp::send_data(const char * data, size_t data_size) {
	UNUSED(data); UNUSED(data_size);
	_throw_error( std::runtime_error("Use send_data_udp") );
}
void parser::pop_byte_skip(char c) { // read expected character (e.g. a delimiter)
	unsigned char was = pop_byte_u();
	unsigned char expected = static_cast<unsigned char>(c);
	if (was != expected) _throw_error( format_error_read_delimiter() );
}